简体   繁体   中英

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.

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 ?

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". 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.)

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:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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