2010-04-12 5 views
11

В классах, реализующих INotifyPropertyChanged Я часто вижу эту картину:Если сеттер немедленно возвращается, если ему присвоено такое же значение?

public string FirstName 
    { 
     get { return _customer.FirstName; } 
     set 
     { 
      if (value == _customer.FirstName) 
       return; 

      _customer.FirstName = value; 

      base.OnPropertyChanged("FirstName"); 
     } 
    } 

именно на линии

  if (value == _customer.FirstName) 
       return; 

мне надоели. Я часто делал это, но я не уверен, что это необходимо или хорошо. В конце концов, если вызывающий абонент присваивает то же самое значение, я не хочу переназначать это поле и, особенно, уведомлять своих подписчиков о том, что свойство изменилось, когда семантически это не произошло.

За исключением сохранения некоторых CPU/RAM/etc, освобождая пользовательский интерфейс от обновления чего-то, что, вероятно, будет выглядеть одинаково на экране/what_medium, что мы получим?

Могут ли некоторые люди принудительно обновить, переназначив одно и то же значение на имущество (НЕ ТО, ЧТО ЭТО БЫЛО ХОРОШЕЙ ПРАКТИКИ ОДНАКО)?

1. Должны ли мы это делать или не должны?

2. Почему?

ответ

9

Да, вы должны немедленно вернуться, когда потребитель устанавливает значение свойства, равное значению, которое уже сохраняется.

Прежде всего, нет причин тратить время и ресурсы в настройщике свойства - значение уже установлено, поэтому никаких дальнейших действий не требуется. Также вы никогда не должны звонить OnPropertyChanged, если значение, сохраненное в поле поддержки свойства, не изменилось - метод должен быть поднят, когда значение изменилось, когда не был вызван сеттер свойства.

Все, что было сказано, однако, если у сеттера не было звонка на OnPropertyChanged, я бы не потрудился сначала проверить значение. В случае простого сеттера, который устанавливает только значение поля поддержки и ничего больше, на самом деле будет быстрее всегда устанавливать значение, а не проверять сначала, а затем устанавливать значение. Используйте этот шаблон только в том случае, если у установщика свойств есть дополнительная логика, которая либо не должна срабатывать, либо может повлечь ненужное снижение производительности.

+2

Я думаю, что не согласен с тем, что ваш № 2 прав. В зависимости от того, что делается. Сравнение двух строк намного дороже, чем настройки ссылки на строку. Также вы добавили обработку всегда, даже если они разные. – galford13x

+0

Чтобы добавить к моему предыдущему заявлению, вызов OnPropertyChanged может все же быть желательным в зависимости от намерения. Могут быть моменты, даже если значение не изменилось, вы можете захотеть ввести событие OnPropertyChanged только потому, что оно было введено. – galford13x

2

Единственный аргумент против этого шаблона (где вы вернетесь, если значение не изменилось). Я могу думать, что точка зрения пуриста состоит в том, что каждая функция должна иметь только один выход. Не будучи пуристом, я не согласен. Я не вижу ничего плохого в том, чтобы вырваться, если значение не изменилось, избегая обновления уведомлений.

+3

Я никогда не был убежден * одним путем выхода к каждой точке функции/метода *. – voyager

+0

Я лично сталкиваюсь со слишком многими сценариями, где невозможно ограничить каждую функцию одним путем выхода без ненужного разделения ее на несколько функций, и даже тогда ее не всегда можно избежать без обфускации кода (если более половины функции находится внутри блока 'else', ИМХО, вы делаете это неправильно). –

7

Или вы могли бы сделать это:

set 
    { 
     if (value != _customer.FirstName) 
     { 

      _customer.FirstName = value; 

      base.OnPropertyChanged("FirstName"); 
     } 
    } 

Нет необходимости в нескольких путей возвращения.

Чтобы ответить на ваш вопрос, я не стал бы принудительно обновлять свойство, если оно будет перезаписано одним и тем же значением. На самом деле нет смысла, потому что вы, вероятно, не получите от этого никакой пользы. (Я мог видеть экземпляр, где вы хотите отслеживать каждый раз, когда кто-то пытается обновить значение.)

+0

В любом случае, я думаю, что то, о чем он спрашивает, касается не точного кода, а скорее, если это действительно так, чтобы избежать выполнения кода установщика при повторяющихся настройках. (Работайте как 'PUT', а не как' POST' для вас, ребята из веб-разработчиков.) – voyager

+3

Не нужно также увеличивать вложенность. :) – ANeves

+0

На самом деле многие думают, что вы не должны опускать {} на оператор if так: if (..) {return;}. Все еще вложенность, и у вас много обратных путей. – kemiller2002

1

Единственная ситуация, когда вы не использовать это, когда вы знаете, что вы можете иметь грязные данные о вашем классе, например, на объекте ORM слоя, который может иметь устаревшие значения по сравнению с основной базой данных из-за модификации другим пользователем.

Если эта ситуация не повлияет на вас, тогда пройдите!


Редактировать

Я понял ваш вопрос, как вы говорите о сеттеры, а не геттеры.

Аналогичные баллы применяются. Если заданная операция является дорогостоящей и не должна иметь какого-либо побочного эффекта (это не должно быть) Побочные эффекты на сеттерах: <blink>evil</blink> !! 1), то это действительная оптимизация.

1

Одна из причин не вернуться раньше, я бы предположила, это для подписчиков, которые присоединились к партии поздно. Они могут не знать о текущем состоянии объекта и будут упускать уведомление об установке, если вы вернетесь раньше.

+1

Либо поздние столяры питались текущим значением, когда они присоединились, либо это не имело значения: если они это сделали, их не нужно обновлять; если они этого не сделали, они решили игнорировать его и не нуждались в уведомлении об изменениях, которых не было. В любом случае, поднятие события не имеет значения. – ANeves

+0

@sr, вы делаете акцент на значении *. Я уделяю больше внимания * событию *, которое вызвало значение (не то, что значение несущественно, но оно вторично для самого события). существуют вполне допустимые варианты использования, когда какой-то другой объект должен знать только ценность, как это произошло, и не обязательно интересуется тем, что произошло до его подписания. если вы не можете думать о таком прецеденте, дайте мне знать, и я приведу вам несколько примеров. – Anurag

+0

Я ценю, что вы сделали это, что очень важно для некоторых приложений.Недавно мне пришлось обновить аспектно-ориентированное решение для применения уведомлений об изменении свойств, поскольку аспект всегда возвращался немедленно, если значение было равным. Это то, чего я хочу большую часть времени, но я столкнулся с прецедентом, чтобы заинтересоваться самим событием, а не фактическим значением. Теперь у меня есть аспекты, которые могут сделать. Я вижу аргумент за то, что у меня есть отдельное событие, чтобы наблюдать скорее, чем событие «на изменение». – DannyMeister

 Смежные вопросы

  • Нет связанных вопросов^_^