Автосвойства


#1

Предлагаю вернутся к этой теме, и всё же обсудить - как это может быть реализовано.

Моё предложение состоит в том чтоб сделать описание возможности записи и чтения как у интерфейсов:

Unit1:

unit Unit1;

type
  t1 = class
    auto property Prop1: integer read write;
    auto property Prop2: integer read;
    
    procedure p1;
    begin
      //внутри класса можно и читать и перезаписывать все авто свойства,
      //потому что в данном случае идёт обращение к внутреннему приватному полю,
      //а к ним можно обращатся из любой части класса
      Prop1 += 1;
      Prop2 += 1;
    end;
  end;

begin
  var a := new t1;
  
  a.Prop1 += 1;//тут есть оба, и read и write, поэтому можно
  
  a.Prop2 += 1;//тут вроде тоже можно, из затого что приватные поля видно из всего поля
               //но это уже спорный момент
  
end.

Основная программа:

uses Unit1;

begin
  var a := new t1;
  
  a.Prop1 += 1;//Тут есть оба, и read и write, поэтому можно
  
  a.Prop2.Print;//Читать можно
  a.Prop2 := 1;//А вот записывать уже нельзя
  
end.

Unit1 будет разворачиваться в:

unit Unit1;

type
  t1 = class
    private $Prop1:integer;
    private $Prop2:integer;
    
    internal property Prop1: integer read $Prop1 write $Prop1;
    internal property Prop2: integer read $Prop2;
    
    internal procedure p1;
    begin
      $Prop1 += 1;
      $Prop2 += 1;
    end;
  end;

begin
  var a := new t1;
  
  {
  //стоит ли разрешать?
  a.$Prop1 += 1;
  a.$Prop2 += 1;
  {}
  //(вариант если НЕ разрешать)
  a.Prop1 += 1;
  //a.Prop2 += 1;//не откомпилируется
  {}
  
end.

Кто что думает о таком синтаксисе? У кого есть другие идеи? Давайте писать сюда.


#2

Правильно ли я понимаю, что автосвойства отличаются от полей лишь возможностью задать уровень доступа read?


#3

Если смотреть с этой стороны - да, относительно полей это единственное отличие.

Но как @VladislavMoldovan правильно подметил в #844 - в .Net очень редко оставляют публичные поля. Даже если подключившему библиотеку можно и читать и записывать их - их всё равно оборачивают в свойство.


#4

Расскажите мне, зачем. Слова “так делают” меня не убеждают.


#5

Отсюда я прочитал что основное преимущество - это возможность не ломать библиотеку, если понадобится в будущих версиях поставить какую то логику на запись или чтение свойства. То есть, вот был тип в библиотеке:

  t1=class
    public data1:real;
  end;

Кто то пользовался этой библиотекой, создал свой .exe на её основе. Теперь, нам вдруг понадобилось выписывать data1 когда его перезаписывают:

  t1=class
    private _data1:real;
    
    public property data1:real read _data1 write
    begin
      _data1 := value;
      writeln(_data1);
    end;
  end;

Теперь, если обновить до этой версии .dll, не обновив .exe - .exe сломается. А если бы data1 было свойством с самого начала - ничего бы не сломалось.

Так же там было про то что для полей не работает Remoting, доступ через System.Reflection и data binding, но за то что правильно понял эту часть я ручиться не могу.


#6

Ну, я всё это более-менее знаю. Не впечатляет если честно. Reflection для полей несомненно работает. Стандартный binding там конечно - основное. Но он приличным образом делается только в xml - вна голом C# надо написать тьму кода.

exe будут не работать с новыми dll без перекомпиляции по огромному количеству причин - это всего лишь одна из многих. Поэтому лучше exe всё же перекомпилировать тоже.


#7

Извиняюсь, что спустя месяц, но

Это затем, чтобы не нарушать логику. Допустим, имеем класс:

Type Layer = Sealed Class
  Public InputWidth: Int32;
  Public InputHeight: Int32;
  Public InputDepth: Int32;
  Public OutputWidth: Int32;
  Public OutputHeight: Int32;
  Public OutputDepth: Int32;
  Public Constructor Create();
  Begin
  End;
End;

Выглядит привычно. Поля класса. Но вот если посмотреть извне, то получается, что размеры входа и выхода - просто данные слоя(так как выглядят полями). А на самом деле - это именно свойства слоя, но они ведь должны где-то лежать. На практике - да, это имеет мало смысла, но вот интерфейс класса или структуры они способны значительно улучшить. У открытых полей своё назначение. А если так делают, то не “просто так, чтобы было”. Не дураки ведь. Сам поначалу не видел в этом смысла, но как дошло до реализации больших классов внутри dll, моё мнение поспешило измениться(само :smile: ).