在构造函数

时间:2016-08-04 21:33:44

标签: c# dependency-injection

我试图将PropertyChangedEventHandler作为参数传递给构造函数,目标是该参数在传递时可以订阅基类中的PropertyChanged事件。

public class Caller : BaseClass{

    public Caller() : base(OnPropertyChanged){
        //
    }

    private void OnPropertyChanged(object sender, PropertyChangedEventArgs eventArgs){
        // handle stuff
    }
}

public class BaseClass : INotifyPropertyChanged{

    public BaseClass(PropertyChangedEventHandler handler){
        PropertyChanged += handler;
    }
}

现在,我知道你在想什么:你为什么不注入Caller而不是方法呢?嗯,首先,你不能在{c}中注入this。此外,这些课程是父母/子女等级制度的一部分,其中父母知道他们的孩子而不是相反的方式(在我的情况下应该是这样),所以我不能继续告诉孩子关于它的父母,并以PropertyChanged那样联系。

编译器告诉我:

  

无法访问非静态方法' OnPropertyChanged'在静态环境中。

我无法使OnPropertyChanged静态。这毫无意义。

有没有办法在我的限制范围内解决这个问题?解决方法很好,只要Caller永远不会直接传递到BaseClass

编辑: 为了澄清,Caller不能引用PropertyChanged本身,因为它将是错误的(它将是它自己的,而不是孩子的)。我只是把它隐藏起来以保持代码清洁。对于那些感兴趣的人,我实际上是Func,我在那里调用创建子项的基类并接受OnPropertyChanged方法。

1 个答案:

答案 0 :(得分:1)

  

为什么不注入Caller而不是方法呢?嗯,首先,你不能把它注入一个ctor

如果您了解这一点,那么您还应该了解为什么不能使用方法名称。在需要delegate引用的位置使用方法名称时,编译器会自动为您创建代码以创建delegate实例。

当方法是实例方法时,delegate除了目标方法本身之外还需要实例引用。当您没有明确提供实例时,会使用什么参考?那是对的:this

但正如您已经注意到的那样,您无法注入"构造函数中的this。或者更准确地说,在对象完全初始化之前,您不允许在构造函数之外使用this。无法使用方法名称与在同一上下文中无法使用this完全相同。

执行类似这样的操作的正确方法,派生类需要能够为基类希望能够调用的方法提供实现,即将基类中的方法声明为{{1 }或virtual然后让派生类覆盖方法。

例如:

abstract

注意我还从方法声明中删除了public class Caller : BaseClass{ protected override void OnPropertyChanged(PropertyChangedEventArgs eventArgs){ // handle stuff } } public abstract class BaseClass : INotifyPropertyChanged{ protected abstract void OnPropertyChanged(PropertyChangedEventArgs eventArgs); } 参数。通常,此模式既用于提供引发事件的基本实现机制,也用于派生类对事件进行某种控制的方式(例如在提升之前或之后进行一些处理事件,甚至在事件发生之前修改事件args)。因此,sender始终为sender,因此不需要包含它。

换句话说,更典型的是,基类实际上会有一个实现,而不是方法this,而实现将是引发事件的地方。