Предлагаю вернутся к этой теме, и всё же обсудить - как это может быть реализовано.
Моё предложение состоит в том чтоб сделать описание возможности записи и чтения как у интерфейсов:
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.
Кто что думает о таком синтаксисе? У кого есть другие идеи? Давайте писать сюда.
Если смотреть с этой стороны - да, относительно полей это единственное отличие.
Но как @VladislavMoldovan правильно подметил в #844 - в .Net очень редко оставляют публичные поля. Даже если подключившему библиотеку можно и читать и записывать их - их всё равно оборачивают в свойство.
Отсюда я прочитал что основное преимущество - это возможность не ломать библиотеку, если понадобится в будущих версиях поставить какую то логику на запись или чтение свойства. То есть, вот был тип в библиотеке:
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, но за то что правильно понял эту часть я ручиться не могу.
Ну, я всё это более-менее знаю. Не впечатляет если честно. Reflection для полей несомненно работает.
Стандартный binding там конечно - основное. Но он приличным образом делается только в xml - вна голом C# надо написать тьму кода.
exe будут не работать с новыми dll без перекомпиляции по огромному количеству причин - это всего лишь одна из многих. Поэтому лучше exe всё же перекомпилировать тоже.
Это затем, чтобы не нарушать логику. Допустим, имеем класс:
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, моё мнение поспешило измениться(само ).
@Admin, на какой стадии разработки автосвойства? Планируется ли их внедрять в скором будущем в PascalABC.Net или их реализация откладывается на более длительный срок? Хотелось бы услышать Ваши планы на это счёт (если они имеются, разумеется).
Ну, как минимум их можно делать только читаемыми вне модуля, с полями вы отказались так делать. А так - там полно мелких причин, как совместимость версий библиотек (можно заменить авто свойство на обычное свойство, без потери совместимости), или того, что на .Net не принято делать публичные поля классам, всё публичное должно быть свойствами.
А как их сделать только читаемыми вне модуля? Я так понимаю, что вы хотите модификаторы get; private set. Но так усложнять язык мы несомненно не будем.
Нет, просто read без write поставить. В модуле где оно описано - можно всё равно будет перезаписывать, потому что если было бы приватное поле из которого это свойство что то читает - оно было бы доступно по всему модулю.
Вот как раз чтоб не усложнять язык - пусть так работает, то есть полностью отражает по функционалу как если было бы приватное поле+свойство. Но чтоб при этом записывалось по другому.