Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 09.05.07 07:37
Оценка: 102 (10)
Добавил поддержку auto-property (как в C# 3.0).

Теперь для описания свойства которой только пишет и читает перменные можно использовать синтаксис:
public Prop1 : int { get; private set; }
public Prop2 : int { get; set; }


Пример использования:
using System.Console;

public class A
{
  public this(i : int) { Prop1 = i; }
  public Prop1 : int { get; private set; }
  public Prop2 : int { get; set; }
}
 
module Program
{
  Main() : void
  {
    def a = A(123);
    a.Prop2 = 789;
    WriteLine($"a.Prop1=$(a.Prop1); a.Prop2=$(a.Prop2);");
    _ = ReadLine();
  }
}


Особую гордость вызывает объем и чистота кода котрый пришлось добавить для реализации этой возможности.
Вот он весь:
// Support autoproperty (see C# 3.0 specification).
// убеждаемся, что это не абстракное или extern- свойсво, что это не индексер (т.е. нет параметров) и не член интерфейса.
when (!(propertyAst.Attributes %&& (NemerleAttributes.Abstract | NemerleAttributes.Extern)) 
      && !IsIndexer && !par.IsInterface)
  match (propertyAst.get, propertyAst.set)
  {
    | (Some(PT.ClassMember.Function(_, _, FunBody.Abstract) as getr), // распознаем, что getter и setter абстрактны (не имеют тел)
       Some(PT.ClassMember.Function(_, _, FunBody.Abstract) as setr)) => // за одно "выцепляем" ссылки на сами getter и setter.

      def field = Macros.NewSymbol("field"); // Генерируем новое имя для поля, которое будет хранить значение свойства
      par.Define(<[ decl: mutable $(field : name) : $(propertyAst.ty); ]>); // Добавляем поле это поле

      // Формируем тела getter-а и setter-а, так чтобы они использовали добавленное выше поле.
      getr.Body = <[ $(field : name) ]>;
      setr.Body = <[ $(field : name) = value ]>;

    | _ => ()
  }

Этот код находится в http://nemerle.org/svn/nemerle/trunk/ncc/hierarchy/ClassMembers.n

ЗЫ

Казалось бы сколько времени пользуюсь паттерн-матчингом и квази-цитированием, но блин вот от таких вещей порой просто прет (в хоршем смысле этого слова (с)).
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Добавил поддержку auto-property (как в C# 3.0)
От: IT Россия linq2db.com
Дата: 09.05.07 10:48
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Добавил поддержку auto-property (как в C# 3.0).


А только getter или только setter можно задать?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 09.05.07 11:04
Оценка: +1
Здравствуйте, IT, Вы писали:

IT>А только getter или только setter можно задать?


Нет. В этом нет смысла. Поле то ведь скрытое.

Вообще спецификацию C# писали разумные люди .
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Добавил поддержку auto-property (как в C# 3.0)
От: IT Россия linq2db.com
Дата: 09.05.07 17:43
Оценка:
Здравствуйте, VladD2, Вы писали:

IT>>А только getter или только setter можно задать?


VD>Нет. В этом нет смысла.


— Ты суслика видишь? — Нет! — А он есть! (c)

VD>Поле то ведь скрытое.


Это детали исключительно твоей реализации. При использовании атрибута Accessor (или как там его) получаемого в результате свойтва тоже не видно. А оно есть!

VD>Вообще спецификацию C# писали разумные люди .


Спецификацию C# на foreach тоже писали разумные люди. Только это не помешало в N сделать его гораздо мощьнее.

Вообще-то, я вот к чему. В bltoolkit можно практически также объявлять свойства даже в C# 1.1. Разница только в том, что эти свойтсва должны быть абстрактные. Для них можно указать только геттер или только сеттер. Абстрактные свойства используется для того, чтобы можно было генерировать реализацию свойств не просто как переменную типа как у свойства, а немного другую. Например, иногда полезно что-то добавить в сеттер, иногда сделать реализацию свойства типа double как EditableValue<double>.

Но проблема с абстрактными классами нам всем хорошо известна. В N это всё можно было бы решить гораздо изящней. Поэтому не хотелось бы получить его сразу в таком ограниченном виде.
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.05.07 09:34
Оценка:
Здравствуйте, IT, Вы писали:

IT>Это детали исключительно твоей реализации.


Нет. Это следствие гигиеничности макросов.

IT> При использовании атрибута Accessor (или как там его) получаемого в результате свойтва тоже не видно. А оно есть!


Предлагаю все же перед обсуждением разобраться в сути проблемы.
Свойство получаемое в результате работы атрибута Accessor видно программисту в лучшем виде. Ты можешь ссылаться на него, "видеть" его в интелесенсе.

Переменна же от автопроперти не видна никак кроме раве что Рефлектором. Система макросов даем ему имя _N_имяПоляXXX где XXX — это каждый раз новое число. Так что при всем желании обратиться к этому полю не выйдет.

IT>Вообще-то, я вот к чему. В bltoolkit можно практически также объявлять свойства даже в C# 1.1. Разница только в том, что эти свойтсва должны быть абстрактные. Для них можно указать только геттер или только сеттер. Абстрактные свойства используется для того, чтобы можно было генерировать реализацию свойств не просто как переменную типа как у свойства, а немного другую. Например, иногда полезно что-то добавить в сеттер, иногда сделать реализацию свойства типа double как EditableValue<double>.


IT>Но проблема с абстрактными классами нам всем хорошо известна. В N это всё можно было бы решить гораздо изящней. Поэтому не хотелось бы получить его сразу в таком ограниченном виде.


Здорово. Только автопроперти тут все же не причем. Если ты что-то будешь делать, то сам сможешь реализовать нужное тебе поведение. А автопроперти всего лишь фича языка позволяющая упроститть ординарный код.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Добавил поддержку auto-property (как в C# 3.0)
От: rameel https://github.com/rsdn/CodeJam
Дата: 10.05.07 10:46
Оценка:
Здравствуйте, VladD2, Вы писали:

Обновился с репозитория, ошибка компиляции во второй фазе, эти изменения могут вызвать такую ошибку?
\Projects\Nemerle\ncc\hierarchy\TypeInfo.n(80,24,80,27): error : interface method cannot have body
\Projects\Nemerle\ncc\hierarchy\TypeInfo.n(80,29,80,32): error : interface method cannot have body
\Projects\Nemerle\ncc\hierarchy\TypeInfo.n(95,28,95,31): error : interface method cannot have body
\Projects\Nemerle\ncc\hierarchy\TypeInfo.n(95,33,95,36): error : interface method cannot have body
\Projects\Nemerle\tools\msbuild-task\Compiler.MSBuild.targets(167,9): error : interface members are not allowed to have any attributes specified, except 'new'
\Projects\Nemerle\tools\msbuild-task\Compiler.MSBuild.targets(167,9): error : fields cannot be defined inside interface
\Projects\Nemerle\tools\msbuild-task\Compiler.MSBuild.targets(167,9): error : interface members are not allowed to have any attributes specified, except 'new'
\Projects\Nemerle\tools\msbuild-task\Compiler.MSBuild.targets(167,9): error : fields cannot be defined inside interface
... << RSDN@Home 1.2.0 alpha rev. 677>>
Re[2]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.05.07 11:53
Оценка:
Здравствуйте, rameel, Вы писали:

R>Обновился с репозитория, ошибка компиляции во второй фазе, эти изменения могут вызвать такую ошибку?


Уже знаю. Не учел что пустые методы еще и в интерейсах бывают. Вот думаю как лучше исправить.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Добавил поддержку auto-property (как в C# 3.0)
От: Аноним  
Дата: 10.05.07 12:04
Оценка:
Здравствуйте, rameel, Вы писали:

R>Обновился с репозитория, ошибка компиляции во второй фазе, эти изменения могут вызвать такую ошибку?


Аналогично.
COMPILE [stage2] Nemerle.Compiler.dll
______......................................................
hierarchy/TypeInfo.n:80:24:80:27: ←[01;31merror←[0m: interface method cannot hav
e body
hierarchy/TypeInfo.n:80:29:80:32: ←[01;31merror←[0m: interface method cannot hav
e body
hierarchy/TypeInfo.n:95:28:95:31: ←[01;31merror←[0m: interface method cannot hav
e body
hierarchy/TypeInfo.n:95:33:95:36: ←[01;31merror←[0m: interface method cannot hav
e body
←[01;31merror←[0m: interface members are not allowed to have any attributes spec
ified, except 'new'
←[01;31merror←[0m: fields cannot be defined inside interface
←[01;31merror←[0m: interface members are not allowed to have any attributes spec
ified, except 'new'
←[01;31merror←[0m: fields cannot be defined inside interface
make[3]: *** [out.stage2/Nemerle.Compiler.stage2.dll] Error 1
make[3]: Leaving directory `/work/nemerle/ncc'
make[2]: *** [aux-stage] Error 2
make[2]: Leaving directory `/work/nemerle/ncc'
make[1]: *** [stage2] Error 2
make[1]: Leaving directory `/work/nemerle/ncc'
make: *** [all] Error 2
Re[3]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.05.07 13:48
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Аналогично.


Это ежу понятно .

Я уже поправил баг, но застрял на сообщениях об ошибках. Я ранее поменял текстовое отображение для свойств и полей и оно теперь вылезло в тестах. Ща поправлю и залью.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.05.07 15:03
Оценка: 15 (1)
Здравствуйте, rameel, Вы писали:

R>Обновился с репозитория, ошибка компиляции во второй фазе, эти изменения могут вызвать такую ошибку?


Исправил и залил. За одно обновил корневое сообщение, чтобы оно соответствовало современной действительности.
Код получился еще проще . Удалось избавиться от использования макросв и за одно позволить добавлять автопроперти в макросах, а не только в коде.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Добавил поддержку auto-property (как в C# 3.0)
От: _FRED_ Черногория
Дата: 10.05.07 16:12
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Добавил поддержку auto-property (как в C# 3.0).


Жаль, что для свойств строкового типа, коих в классах, где хотелось бы применить эту фичу, у меня чуть не треть, такой подход неприемлем: в соответствии с guidelines свойства перечислимых типов не должны возвращать null и они у меня описаны так (C#):
get { return field ?? String.Empty; }

Макрос же таким фокусам (без хардкодинга) не научить :о(
Help will always be given at Hogwarts to those who ask for it.
Re[3]: Добавил поддержку auto-property (как в C# 3.0)
От: rameel https://github.com/rsdn/CodeJam
Дата: 10.05.07 16:27
Оценка:
Здравствуйте, VladD2, Вы писали:

О, вот теперь все пучком, я даже заменил несколько мест у себя в проекте, где использовался Accessor на автопроперти
... << RSDN@Home 1.2.0 alpha rev. 677>>
Re[2]: Добавил поддержку auto-property (как в C# 3.0)
От: Блудов Павел Россия  
Дата: 11.05.07 01:00
Оценка: 6 (1) +1
Здравствуйте, _FRED_, Вы писали:

_FR>
_FR>get { return field ?? String.Empty; }
_FR>

_FR>Макрос же таким фокусам (без хардкодинга) не научить :о(
Ну почему, можно доработать напильником примерно до такого вида
[NullValue("")]
public Foo : string { get; set; }

Соответственно если задано NullValue и тип свойства есть ref или nullable, то можно добавить проверку и возвращать подправленное значение.
Только лучше оставить auto-property в покое и доработать макрос Accessor.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Re[2]: Добавил поддержку auto-property (как в C# 3.0)
От: _pk_sly  
Дата: 11.05.07 06:38
Оценка: +1
IT>А только getter или только setter можно задать?

да, было бы неплохо...
для тех же read-only и write-only значений
либо когда одно хотелось бы оставить стандартом, а второе поменять.
Re[3]: Добавил поддержку auto-property (как в C# 3.0)
От: Иванков Дмитрий Россия  
Дата: 11.05.07 06:51
Оценка:
Здравствуйте, _pk_sly, Вы писали:

IT>>А только getter или только setter можно задать?


__>да, было бы неплохо...

__>для тех же read-only и write-only значений
__>либо когда одно хотелось бы оставить стандартом, а второе поменять.

Зачем write-only представить не могу, а вот immutable в принципе могу

Примерно так может выглядеть:
[ImmutableProperty]
public Prop1 : int { public get; };


Что должно сгенерировать immutable field и private set, соответственно set только из конструктора будет работать.
Re[4]: Добавил поддержку auto-property (как в C# 3.0)
От: Иванков Дмитрий Россия  
Дата: 11.05.07 07:20
Оценка:
Здравствуйте, Иванков Дмитрий, Вы писали:

ИД>Здравствуйте, _pk_sly, Вы писали:


IT>>>А только getter или только setter можно задать?


__>>да, было бы неплохо...

__>>для тех же read-only и write-only значений
__>>либо когда одно хотелось бы оставить стандартом, а второе поменять.

ИД>Зачем write-only представить не могу, а вот immutable в принципе могу


Хотя зачем это может пригодиться когда можно обойтись public field?
Re[4]: Добавил поддержку auto-property (как в C# 3.0)
От: _pk_sly  
Дата: 11.05.07 07:56
Оценка:
ИД>Зачем write-only представить не могу, а вот immutable в принципе могу :)

а я могу. и пользовался этим.
и разработчики C# тоже, очевидно, могли, если учли это в спецификации.
даже в COM такая возможность присутствует.
Re[3]: Добавил поддержку auto-property (как в C# 3.0)
От: _FRED_ Черногория
Дата: 11.05.07 09:14
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>Только лучше оставить auto-property в покое и доработать макрос Accessor.


Справедливо. Авто-свойствам лучше так, как уже есть.
Help will always be given at Hogwarts to those who ask for it.
Re[3]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.05.07 12:48
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>Ну почему, можно доработать напильником примерно до такого вида

БП>
БП>[NullValue("")]
БП>public Foo : string { get; set; } 
БП>

БП>Соответственно если задано NullValue и тип свойства есть ref или nullable, то можно добавить проверку и возвращать подправленное значение.
БП>Только лучше оставить auto-property в покое и доработать макрос Accessor.

На самом деле одно другому не мешает.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.05.07 12:48
Оценка:
Здравствуйте, Иванков Дмитрий, Вы писали:

ИД>Зачем write-only представить не могу, а вот immutable в принципе могу


ИД>Примерно так может выглядеть:

ИД>
ИД>[ImmutableProperty]
ИД>public Prop1 : int { public get; };
ИД>


ИД>Что должно сгенерировать immutable field и private set, соответственно set только из конструктора будет работать.



Это бесмысленное занятие. Чтобы сделать private сеттер достаточно написать:
public Prop1 : int { get; private set; }

Получат же доступ к полю просто нет смысла.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.