Не забывайте одну вещь: PropertyChanged
событие в основном используется компонентами, которые используют отражение для получения значения именованного свойства.
Самый очевидный пример - привязка данных.
Когда вы запускаете событие PropertyChanged
, передавая имя свойства в качестве параметра, вы должны знать, что подписчик этого события может использовать отражение , вызывая, например, GetProperty
(по крайней мере, в первый раз, если он использует кэш PropertyInfo
), затем GetValue
. Этот последний вызов является динамическим вызовом (MethodInfo.Invoke) метода получения свойства, который стоит больше, чем GetProperty
, который запрашивает только метаданные. (Обратите внимание, что привязка данных зависит от всего TypeDescriptor , но в реализации по умолчанию используется отражение.)
Так что, конечно, использование имен свойств жесткого кода при запуске PropertyChanged более эффективно, чем использование отражения для динамического получения имени свойства, но ИМХО, важно сбалансировать свои мысли. В некоторых случаях снижение производительности не так критично, и вы могли бы извлечь выгоду из некоего механизма запуска событий со строгой типизацией.
Вот то, что я иногда использую в C # 3.0, когда производительность не будет проблемой:
public class Person : INotifyPropertyChanged
{
private string name;
public string Name
{
get { return this.name; }
set
{
this.name = value;
FirePropertyChanged(p => p.Name);
}
}
private void FirePropertyChanged<TValue>(Expression<Func<Person, TValue>> propertySelector)
{
if (PropertyChanged == null)
return;
var memberExpression = propertySelector.Body as MemberExpression;
if (memberExpression == null)
return;
PropertyChanged(this, new PropertyChangedEventArgs(memberExpression.Member.Name));
}
public event PropertyChangedEventHandler PropertyChanged;
}
Обратите внимание на использование дерева выражений для получения имени свойства и использование лямбда-выражения в качестве Expression
:
FirePropertyChanged(p => p.Name);