-2

考虑以下内置委托:

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
    }
};
4

1 回答 1

0

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

也就是说,如果有与绑定相关的代码正在检查特定的返回值,它可能会失败,因为它没有找到它正在寻找的事件。如果您确定这在您的场景中不是问题(此处定义不明确……完整、最小的代码示例确实有助于此处的问题质量),那么我想您本身不需要担心。

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

于 2015-01-16T08:29:13.633 回答