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.