简体   繁体   English

C#具有继承的事件的强类型“发送者”

[英]C# Strong typed “sender” of events with inheritance

I'm not sure if that is possible in C# but I would like to have events in an abstract class with a strong typed 'sender' argument. 我不确定在C#中是否可行,但我希望在一个带有强类型“发送者”参数的抽象类中有事件。

There is my code 有我的代码

abstract class Base
{
    public degate void MyDelegate(Base sender, object arg);
    public event MyDelegate SomeEvent;

    protected void RaiseSomeEvent(object arg)
    {
        if (SomeEvent != null)
            SomeEvent(this, arg)
    }
}

class Derived : Base
{
    // ?
}

var obj = new Derived();
obj += EventHandler;

public void EventHandler(Derived sender, object arg)
{

}

So is that possible by manipuling generic where clause for example ? 那么可以通过操纵generic where子句来做到这一点吗?

You could definitely make it generic - but you wouldn't really want to in the case that you've given. 你绝对可以把它变成通用的 - 但在你给出的情况下,你真的不想这样做。

Base.SomeEvent doesn't "know" (at compile-time) what type it is - so you can't make it depend on some type parameter which will be "the right type". Base.SomeEvent不“知道”(在编译时)它是什么类型 - 所以你不能让它依赖于某种类型参数,它将是“正确的类型”。 You could do something horrible like: 可以做一些可怕的事情:

abstract class Base<T> where T : Base
{
    delegate void MyDelegate(T sender, object arg);

    public event MyDelegate SomeEvent;

    protected void RaiseSomeEvent(object arg)
    {
        if (SomeEvent != null)
            SomeEvent((T) this, arg)
    } 
}

(You may need (T) (object) this to keep the compiler happy.) (您可能需要(T) (object) this以保持编译器满意。)

And then: 接着:

class Derived : Base<Derived>

but it gets very ugly, and there's nothing to stop this from happening: 但它变得非常丑陋,没有什么可以阻止这种情况发生:

class Evil : Base<Derived>

At that point, the cast will fail when the event is raised. 此时,在引发事件时,强制转换将失败。

I would suggest that if you really want to be sure that the sender is the right type, you ignore the sender parameter and capture the variable you're using to subscribe in the first place: 我建议如果你真的想确定发送者是正确的类型,你可以忽略sender参数并捕获你首先用于订阅的变量:

Derived derived = new Derived();
derived.SomeEvent += (ignored, arg) => DoSomething(derived, arg);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM