扩展中的调用方MemberName(INotifyPropertyChanged)

本文关键字:INotifyPropertyChanged MemberName 调用 扩展 | 更新日期: 2023-09-27 18:29:14

我目前正在实现INotifiyPropertyChanged接口的扩展,您可以阅读以下内容:

INotifyPropertyChanged-事件保持为空

获取更多信息。

现在我想进一步扩展这个扩展,这样我就不需要声明MemberExpression,并且当从集合内部调用它时,CallerMemberName属性将完成其余的工作。

因此,我尝试了以下操作(基于我上一个stackoverflow问题中提供的链接):

public static void Notify(this PropertyChangedEventHandler EventHandler, object sender, 
[CallerMemberName] String propertyName = "")
{
    if (EventHandler != null)
    {
        EventHandler(sender, new PropertyChangedEventArgs(propertyName));
    }
}

这允许我调用这样的方法:

this.PropertyChanged.Notify(this); //with CallerMemberName
this.PropertyChanged.Notify(this, "RandomProperty"); 

现在,我想删除总是编写(this,..)参数的必要性,并这样调用它:

this.PropertyChanged.Notify(); //with CallerMemberName
this.PropertyChanged.Notify("RandomProperty"); 

这怎么可能?

扩展中的调用方MemberName(INotifyPropertyChanged)

简单地说,这是不可能的。你需要3条信息:

  • 事件处理程序实例(左侧的this.PropertyChanged
  • 事件名称(propertyName,由编译器提供)
  • 发送方(sender

sender不能从任何其他信息中推断出来,也没有编译器选项来提供它。然而,坦率地说,我只想使用一个实例方法:

protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
    var handler = PropertyChanged;
    if(handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}

然后呼叫者简单地发出:

OnPropertyChanged(); // job done

当然,您可以让OnPropertyChanged调用您的静态方法,但这似乎没有必要。

在某些方面,感觉我们应该能够传入INotifyPropertyChanged实例,用于sender和访问PropertyChanged,但当然,我们无法从event声明中获得实际的委托