Авто реализованные свойства в С#
Есть ли способ продолжать использовать автоматически реализованные свойства, все еще поднимая событие изменения, например INotifyPropertyChanged, когда вызывается Set?
Вместо:
private string _value;
public string Value
{
get
{
return this._value;
}
set
{
this._value = value;
this.ValueChanged(this,EventArgs.Empty);
}
}
Могу я просто сделать:
public string Value
{
get;
set
{
this.ValueChanged(this,EventArgs.Empty);
}
}
Хотя сеттер выглядит неправильно, возможно ли это сделать, не заполняя мой класс переменными хранилища?
UPDATE: Похоже, что нет стандартного решения для моей ленивой цели, я считаю, что лучшим решением является использование CodeRush или Resharper для создания всех моих резервных хранилищ для меня.
Ответы
Ответ 1
Вы не можете этого сделать. Спецификация для автоматически реализованных свойств довольно ясна:
Автоматически реализовано автоматизировать автоматизированные свойства этот узор. Более конкретно, Не абстрактные объявления свойств допускается использование точек с запятой тела. Оба аксессора должны присутствовать и оба должны иметь точки с запятой, но они могут иметь разные модификаторы доступности. Когда свойство указано следующим образом: поле поддержки автоматически будет генерируется для свойства, и аксессоры будут реализованы для чтения от и писать в это фоновое поле. Имя поля поддержки - компилятор создан и недоступен для пользователя.
Другими словами, они могут иметь только "get;
" и "set;
", с возможностью модификаторов доступа.
Ответ 2
Нет, вы не можете, потому что у вас нет доступа к закрытому полю, сгенерированному для этого свойства
Ответ 3
Быстрый поиск в Google по свойствам "inotifypropertychanged auto" приведет вас к нескольким сообщениям в блоге и статьям на эту тему. Здесь один:
INotifyPropertyChanged автоматическая проводка или как избавиться от избыточного кода
Ответ 4
Это было задано в команде Microsoft за С# 3.0, и они сказали, что подумают об этом, прочитайте здесь.
В комментариях вы найдете больше информации, в том числе, почему это плохая идея, если вам нужно больше контроля, а также способы ее достижения.
Ответ 5
Вы можете использовать некоторую инфраструктуру AOP, например PostSharp.
Но это может снизить производительность и время сборки.
Ответ 6
Поскольку я задал этот вопрос, эта проблема фактически была решена как задача атрибута и сборки:
https://github.com/demigor/kindofmagic
Ответ 7
Такое поведение можно выполнить с помощью генератора типа прокси factory. Я уже сделал это в своей разработке Framework. Если вы используете System.Reflection.Emit, вы можете создать прокси-сервер типа.
Рассмотрим пример ниже:
var a = Proxier<InputType>.CreateInstance(new object[] { }); // object arrays are for different constructors
a.PropertyAccessed += ...
Ответ 8
Надстройка Fody PropertyChanged делает это. Так же, как KindOfMagic, Fody использует Mono.Cecil для изменения IL-сборников .net во время компиляции. Следующий пример приведен в документации PropertyChanged:
Вы пишете:
[ImplementPropertyChanged]
public class Person
{
public string GivenNames { get; set; }
public string FamilyName { get; set; }
public string FullName
{
get
{
return string.Format("{0} {1}", GivenNames, FamilyName);
}
}
}
Что скомпилировано:
public class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
string givenNames;
public string GivenNames
{
get { return givenNames; }
set
{
if (value != givenNames)
{
givenNames = value;
OnPropertyChanged("GivenNames");
OnPropertyChanged("FullName");
}
}
}
string familyName;
public string FamilyName
{
get { return familyName; }
set
{
if (value != familyName)
{
familyName = value;
OnPropertyChanged("FamilyName");
OnPropertyChanged("FullName");
}
}
}
public string FullName
{
get
{
return string.Format("{0} {1}", GivenNames, FamilyName);
}
}
public virtual void OnPropertyChanged(string propertyName)
{
var propertyChanged = PropertyChanged;
if (propertyChanged != null)
{
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
wiki содержит несколько более сложных примеров.
Он доступен с помощью NuGet:
PM> Install-Package PropertyChanged.Fody