C# - 委托专业化

时间:2015-01-15 12:40:03

标签: c# delegates inotifypropertychanged propertychanged system.componentmodel

考虑以下内置委托:

public delegate void PropertyChangedEventHandler(object sender, 
        PropertyChangedEventArgs e);

是否有可能将委托扩展/重载/覆盖此签名:

public delegate void MyPropertyChangedEventHandler(object sender,
        MyPropertyChangedEventArgs e);

其中MyPropertyChangedEventArgs被声明为

public class MyPropertyChangedEventArgs : PropertyChangedEventArgs
{
    public readonly object OldValue;
    public readonly object NewValue;

    public MyPropertyChangedEventArgs(string propertyName, object 
        oldValue, object newValue) : base(propertyName)
    {
        OldValue = oldValue;
        NewValue = newValue;
    }
}

并且拥有该事件的类声明为

using System;
using System.ComponentModel;

// missing delegate decleration

public class Bindable : INotifyPropertyChanged
{
    public event MyPropertyChangedEventHandler PropertyChanged;

    private object _property;
    public object Property 
    {
        get { return property; }
        set 
        {
            var oldValue = _property;
            _property = value;
            OnPropertyChanged("Property", oldValue, value);
        }
    }

    protected void OnPropertyChanged(string name, object oldValue,
            object newValue)
    {
        if (oldValue != newValue && PropertyChanged != null)
            PropertyChanged(this, new MyPropertyChangedEventArgs(name,
                    oldValue, newValue));
    }
}

并且事件订阅应允许访问MyPropertyChangedEventArgs属性,而无需在任何地方输入PropertyChangedEventArgs,并且仍然不会丢失与该属性的开箱即用的XAML绑定。

示例用例:

Bindable bindable = new Bindable();

bindable.PropertyChanged += (sender, args) =>
{
    if (args.OldValue != null)
    {
        // Do Something
    }
};

1 个答案:

答案 0 :(得分:0)

假设MyPropertyChangedEventArgs来自PropertyChangedEventArgs(您在问题中不清楚这一点),那么委托逆转肯定会允许客户代码订阅您的“扩展”PropertyChanged事件使用仅匹配基本PropertyChangedEventHandler的处理程序。这是安全的,因为那些处理程序承诺它们可以接受PropertyChangedEventArgs实例,并且代码将传递的对象实际上是其中之一(虽然更多派生)。

也就是说,如果有与绑定相关的代码检查特定的返回值,它可能会失败,因为它没有找到它正在寻找的事件。如果您确定这不是您的场景中的问题(这里定义不明确...... complete, minimal code example这对问题质量有帮助),那么我猜您不需要担心它本身。

但这样做仍然有点“不确定”的设计。恕我直言,最好定义第二个事件(例如MyPropertyChanged,或者在.NET / C#世界中更具惯用性,PropertyChangedEx具有EventArgs子类的类似名称。然后当属性更改时,引发两个事件。在任何现代计算机(包括移动平台)上,这个最小的额外开销将是完全无关紧要的,并且其好处是更清洁,更易于使用的API。