В C# 6 появилось новое ключевое слово nameof которое позволяет получить строку с именем члена класса, что позволяет существенно упростить написание, например, реализации INotifyPropertyChanged. Зачем он нужен я писал вот здесь. Под катом, я покажу как упростить вызов метода OnPropertyChanged. Ну и покажу какой замечательный атрибут появился в .Net Framework 4.5 благодаря которому, даже nameof больше не нужно.
Итак, немного напомню. У нас есть некоторый класс реализующий упомянутый интерфейс. В интерфейсе объявлено всего одно событие и нам нужно при изменении значений свойств его вызывать. Такой класс может иметь вид:
Как видно, при вызове метода OnProeprtyChanged мы вынуждены передавать строку. Что может привести к тому, что свойство мы переименуем, через рефакторинг изменение распространиться везде кроме этой строки и об изменении свойства никто не узнает.
Решить эту проблему можно применением нового ключевого слова nameof , вот так:
Но и это еще не все. С появлением атрибута [CallerMemberName], у нас есть возможность вообще ничего не передавать в этот метод, он сам будет узнавать имя члена класса который его вызвал:
Стало намного лучше.
Итак, немного напомню. У нас есть некоторый класс реализующий упомянутый интерфейс. В интерфейсе объявлено всего одно событие и нам нужно при изменении значений свойств его вызывать. Такой класс может иметь вид:
public class MyClass : INotifyPropertyChanged
{
private string _myString;
public string MyString
{
get
{
return _myString;
}
set
{
if (value != _myString)
{
_myString = value;
OnPropertyChanged(nameof(MyString));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string p_propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(p_propertyName));
}
}
Как видно, при вызове метода OnProeprtyChanged мы вынуждены передавать строку. Что может привести к тому, что свойство мы переименуем, через рефакторинг изменение распространиться везде кроме этой строки и об изменении свойства никто не узнает.
Решить эту проблему можно применением нового ключевого слова nameof , вот так:
public string MyString
{
get
{
return _myString;
}
set
{
if (value != _myString)
{
_myString = value;
OnPropertyChanged(nameof(MyString));
}
}
}
Но и это еще не все. С появлением атрибута [CallerMemberName], у нас есть возможность вообще ничего не передавать в этот метод, он сам будет узнавать имя члена класса который его вызвал:
public class MyClass : INotifyPropertyChanged
{
private string _myString;
public string MyString
{
get
{
return _myString;
}
set
{
if (value != _myString)
{
_myString = value;
OnPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string p_propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(p_propertyName));
}
}
Стало намного лучше.