Расширенные свойства - вопросы

Предлагаю вынести все вопросы по расширенным свойствам сюда, если Вы, конечно, не против.

Начну я. Почему нельзя использовать лямбды в расширенных свойствах?

type
  T1 = class
    fX: byte;
  end;
  
  T2 = class(T1)
    property Y: byte write (v) -> fX := 0; // Не позволяет использовать лямбду в качестве сеттера.
  end;

begin
end. 

Да, пример надуманный, можно сказать. Но будет ли когда-нибудь такая возможность?

А какое сообщение об ошибке? Вы там Procedure забыли подписать.

Program4.pas(7) : Встречено ‘->’, а ожидался оператор

type T1 = class
  public fX: byte;
end;
type T2 = class(T1)
  public property Y: byte write Procedure(v) -> fX := 0;
end;
begin
end.

Тогда вопрос.

Ругается также. Теми же самыми словами.

Слушаю.

Ну так замазывать надо. Цензура :smile:

Надо делать Issue.

Мы выяснили, что так делать нельзя. Если это планируется исправить разработчиками - да, Issue будет полезна. Если нет - то создавать Issue нет смысла. Предлагаю выслушать одного или двух разработчиков.

1 лайк

Если это будет лишним, Issue закроют.

1 лайк

А лямбды без определения Procedure/Function разве есть?

Судя по справке, да.

begin
  var x: Action0 := procedure() -> exit;
  var y: Func0<integer> := () -> 1;
end.

Насколько помню, в первом случае надо писать procedure, так как без указания что это процедура или функция, компилятор считает ее функцией. В доказательство:

Program8.pas(2) : Невозможно преобразовать функциональный тип в процедурный тип

, если опустить procedure.

Правильно так:

property Y: byte write fX := value;

Ну или в вашем случае:

property Y: byte write fX := 0;

В Issue Вы дали мне код:

type
  TClass = class
  private
    fX: byte;
  
  public
    property X: ()->byte read () -> fX;
  end;

begin end.

. У меня такой вопрос. В read пишется именно то выражение, которое возвращается? Точнее, я думал так: я напишу лямбду, она вернет значение поля fX и возвращаемый тип будет byte.

Если вы имели в виду тот же тип - нет. Так можно:

type
  t1 = class
    property X: real read byte(0);
  end;

begin end.

Но, чтоб преобразовать byte к real - есть operator implicit. А чтоб получить возвращаемое значение лямбды без параметров - надо вызвать Invoke. Смотрите:

begin
  var b:byte;
  var r:real := b;//тут вызывается b.operator implicit():real;
  
  //b := ()->byte(0);//Ошибка: Неверный тип переменной, которой присваивается лямбда-выражение
  var f:()->byte := ()->byte(0);
  b := f;//А так можно. Но не потому что f преобразовывает с помощью "operator implicit", а потому что тут происходит вызов f
         //Вызов лямбды не возможен сразу после её объявления
         //и будет проблематично определять её тип если присваивать её переменной типа - byte а не функции
end.
1 лайк

Синтаксис расширенных свойств таков:

property X: тип read выражение write оператор;

Я сейчас грохну этот Issue с особой жестокостью. Прошу впредь Issue в постановке “пишем всю муть какая придет в голову - то, что не надо - уберут” забыть как класс. Я не железный эту грязь всю вычищать

2 лайка

Вопрос снят.