Fighting with events: Rhino.Mocks strongly typed EventRaiser attempt #2

I just spent good few hours trying to fight awkward limitations of .NET framework in regard to generics, events, delegates and expression trees. And I’m actually not much further than when I started. It bothers me: why put artificial limitations in regard to delegates as generic constraints? I wish I could do:

public IEventManager<T1,T2> Metod<T1,T2,TEvent>(TEvent @event) where TEvent: Func<T1,T2>

(this will not compile, can not use delegates as constraints…) or even better:

public IEventManager<T1,T2> Metod<T1,T2,TEvent>(TEvent @event) where TEvent: void delegate(T1,T2)

This seems to ruin my every idea. Even worse, when I looked for help at Expression Trees, I learned that you can’t have assignments in them, so this will not compile:

public event EventHandler<CancelEventArgs> MyEvent;

 

//somewhere else

Expression<Action<EventHandler<CancelEventArgs>>> exp = x=>MyEvent+=x;

Currently I’m trying to find a way to overcome the fact, that you can’t implicitly cast delegate type to another type with same signature. If I succeed It might be possible to write something roughly similar to:

public class Client

{

    public event EventHandler<CancelEventArgs> MyEvent;

 

    private static void Main(string[] args)

    {

        var repository = new XtoffMockRepository();

        var client = new Client();

        var myEventManager =

            repository.Mock(client.MyEvent);

    }

}

 

public class XtoffMockRepository : MockRepository

{

    public IEventManager<TEvent> Mock<TEvent>(TEvent @event)

    {   ...   }

}

 

public interface IEventManager<T>

{   ...   }

This is however still quite far from what I want to accomplish. In an ideal world, IEventManager<T> would have it’s generic parameter being not TEvent (i.e. EventHandler<CancelEventArgs> in this example) but IEventManager<T1,T2>, where it’s parameters correspond to event method’ parameters (object and CancelEventArgs respectively).

[UPDATE]

As I just noticed I call repository.Mock event inside the class that declares event. This is the only place where passing it as a parameter will work, so this solution will not work either.

Technorati Tags: