2012-06-18 2 views
6

Я нахожу, что я много повторяю, и это, конечно, нехорошо. Поэтому я подумал, могу ли я что-нибудь с этим сделать. Это общий код в моем WPF приложения:Обнаруживание свойства setter

private string _name; 
public string Name 
{ 
    get { return _name; } 
    set 
    { 
     if (_name != value) 
     { 
      _name = value; 
      OnPropertyChanged("Name"); 
     } 
    } 
} 

Так мне было интересно, если я мог бы обернуть сеттер каким-то образом, чтобы сделать его лучше и более удобным для чтения. Одна из идей было что-то вроде этого:

protected void PropertySetter<T>(T property, T value, string name) 
{ 
    if (EqualityComparer<T>.Default.Equals(property, value)) 
    { 
     property = value; 
     OnPropertyChanged(name); 
    } 
} 

Использование так:

private string _name2; 
public string Name2 
{ 
    get { return _name2; } 
    set 
    { 
     PropertySetter<string>(Name2, value, "Name2"); 
    } 
} 

Но я не уверен, что это действительно умный или будет работать, а также с типами Value?

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

+2

Check ReactiveUI для этого поведения, если вы не хотите его использовать, вы можете его скопировать. http://www.reactiveui.net/. 'set {this.RaiseAndSetIfChanged (x => x.PasswordConfirmation, value); } ' –

+1

Добавьте' ref' в свой параметр свойства, и он будет работать и для ValueTypes. – SimpleVar

ответ

2

Да - это вполне приемлемо и нормальный код.

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

public event PropertyChangedEventHandler PropertyChanged; 

private void SetProperty<T>(ref T field, T value, string name) 
{ 
    if (!EqualityComparer<T>.Default.Equals(field, value)) 
    { 
     field = value; 
     var handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(name)); 
     } 
    } 
} 

Wrap этот код внутри класса, который реализует INotifyPropertyChanged, и наследовать объекты данных из этого класса.

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

+0

Да, мои методы OnPropertyChanged обертывают создание локального обработчика. Спасибо, пропустили ключевое слово ref. –

2

Может быть, это может помочь вам

public class ObservableObject : INotifyPropertyChanged 
{ 
    #region Events 
    public event PropertyChangedEventHandler PropertyChanged; 
    #endregion 

    #region Protected Methods 
    protected virtual void SetAndNotify<T>(ref T field, T value, Expression<Func<T>> property) 
    { 
     if (!object.ReferenceEquals(field, value)) 
     { 
      field = value; 
      this.OnPropertyChanged(property); 
     } 
    } 

    protected virtual void OnPropertyChanged<T>(Expression<Func<T>> changedProperty) 
    { 
     if (PropertyChanged != null) 
     { 
      string name = ((MemberExpression)changedProperty.Body).Member.Name; 
      PropertyChanged(this, new PropertyChangedEventArgs(name)); 
     } 
    } 
    #endregion 
} 

Использование:

private String _myField; 
    public String MyProperty 
    { 
     get 
     { return _myField; } 
     set 
     { SetAndNotify(ref _myField, value,() => MyProperty); } 
    } 

Edit: Ваш класс должен наследовать от этого класса OservableObject

+1

Никогда не вызывайте 'PropertyChanged' напрямую - есть условия гонки, которые приведут к сбою. Вместо этого всегда создавайте локальную копию и вызывайте ее. – qJake

+0

Имеет ли свойство отражения выражения MemberExpression какие-либо недостатки, например, по производительности или ситуации, когда они не работают? –

+0

@ IngóVals Я реализовал этот класс в двух проектах, которые я разработал, и до сих пор не было проблем – Dante

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