包装属性设置器

时间:2012-06-18 15:57:01

标签: c# properties wrapper

我发现自己很重复,这当然不好。所以我想知道我是否可以为此做些什么。这是我的WPF应用程序中的常用代码:

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

所以我想知道我是否可以以某种方式包装setter以使其更好,更具可读性。一个想法是这样的:

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类型一样好用?

我想我不是第一个尝试类似这样的人,所以如果有人知道一个很好的万无一失的方式来这样的话请插入。我想我不能让财产改变类型安全没有反思,但任何想法会有也有帮助。

2 个答案:

答案 0 :(得分: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); }
    }

编辑:您的班级必须继承此OservableObject班级

答案 1 :(得分: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));
        }
    }
}

将此代码包含在实现INotifyPropertyChanged的类中,并从此类继承数据对象。

在您的示例中,您直接调用该事件 - 从不这样做。从方法启动到调用事件时,您可能会丢失事件引用。 始终在调用之前创建事件的本地缓存。