INotifyPropertyChanged и propertyName — Измененный идентификатор и propertyName

#c# #.net #inotifypropertychanged

#c# #.net #inotifypropertychanged

Вопрос:

Я никогда не был уверен в значении propertyName при реализации INotifyPropertyChanged . Итак, обычно вы реализуете INotifyPropertyChanged как:

 public class Data : INotifyPropertyChanged {
   public event PropertyChangedEventHandler PropertyChanged;

   private void NotifyPropertyChanged(string propertyName = "") {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

   private string itsID;
   public string ID { 
             get { return itsID; }
             set { 
                   if (itsID != value) {
                     itsID = value; 
                     NotifyPropertyChanged("ID");
                  }
   }
}
  

Я никогда не был уверен в propertyName аргументе для NotifyPropertyChanged(string propertyName) .

  1. Может ли это быть любая произвольная строка (например, «MyID» в приведенном выше примере)?
  2. Или делает .NET использует отражение, чтобы выровнять его со свойством в классе, чтобы оно точно соответствовало имени свойства?
  3. Что делать, если propertyName название Property не соответствует в точности имени, делает .NET рассматривает весь объект как changed ?

Комментарии:

1. Просто замечание по технике безопасности: при выполнении if (PropertyChanged != null) старайтесь избегать этого, поскольку возможно, что после null проверки PropertyChanged действительно может быть null снова. Вместо этого безопаснее / лучше сначала установить локальную переменную, а затем проверять. например, var handler = PropertyChanged; if (handler != null) { handler()... // raise } — или из C # 6 вы можете использовать новый «условный оператор null»: PropertyChanged?.Invoke(...) который удваивается как null проверка и одновременный вызов.

2. Это довольно хорошо объяснено здесь ( cs.colorado.edu /~kena/classes/5448/f12/presentation-materials / … ) и я думаю, что это . ЧИСТЫЙ исходный код, который выполняет фактическое отслеживание всех этих ( referencesource.microsoft.com/#System.Data.Services . Клиент/… ). WPF в основном подписывается на события изменения свойств, а затем использует аргументы события, одним из которых является строка, которую вы используете для идентификатора, например, MyID , а затем использует это для обновления элемента управления.

Ответ №1:

Это не сам .NET Framework как таковой, это почти каждый PropertyChanged подписчик (некоторые из которых действительно распространяются как часть фреймворка) предполагает, что вы используете интерфейс по назначению, отправляя имя свойства. Если вы отправляете уведомление о том, что свойство MyID изменилось, когда другой компонент просматривает свойство ID , он, как правило, увидит уведомление, сравнит имена и сделает вывод «это уведомление не для меня».

Ответ №2:

Если вы хотите точно соответствовать имени свойства, вы можете использовать новую функцию C # 6 под названием nameof . nameof Функция отвечает на все ваши вопросы, потому что мы могли бы одним словом сказать, что главное преимущество использования nameof — это рефакторинг. И «рефакторинг» — это слово, которое вы ищете, исходя из ваших вопросов:

 NotifyPropertyChanged(nameof(ID));
  

В качестве примера, переименование ID также изменит имя свойства, или это приведет к прерыванию компиляции, но следующее этого не делает:

 NotifyPropertyChanged("ID")
  

Комментарии:

1. C # 6 здесь мало что добавляет: C # 5 уже предоставил [CallerMemberName] атрибут. NotifyPropertyChanged(); оставляет еще меньше места для опечаток. Тем не менее, это должен быть комментарий, он не пытается ответить на вопрос.

2. @hvd Да. Но самый удобный вариант nameof для меня — это при работе с INotifyPropertyChanged интерфейсом.

3. @hvd На самом деле это многое добавляет. Теперь вы можете связывать данные более эффективно. Просто щелкните правой кнопкой мыши и найдите все ссылки при использовании nameof . Намного лучше, чем это CallerMemberName .

4. @Alexandru nameof безусловно, имеет свои применения, но здесь мы говорим о ссылке внутри средства установки свойств. Вы бы уже обнаружили это без какой-либо функции IDE.

5. @hvd Да, но случаи для NotifyPropertyChanged также существуют за пределами самих установщиков свойств, с которыми nameof мог бы справиться разработчик. Это просто меньше поводов для беспокойства и больше организации, и это то, что мне нравится.

Ответ №3:

Оно должно точно соответствовать имени свойства. Кроме того, вы должны проверить, действительно ли значение изменилось, прежде чем вызывать PropertyChanged, поскольку это относительно дорогостоящий вызов (WPF не будет знать, что свойство не изменилось). В VS2015 вы также можете использовать оператор nameof.

Комментарии:

1. что произойдет, если они не совпадут?

2. @Denis, пользовательский интерфейс обновляться не будет. Привязки выполняются по имени.