Some strange behavior with the C# 4.0 co- and contravariance support:
using System;
class Program {
static void Foo(object x) { }
static void Main() {
This solution was originally posted by cdhowie for my question: Delegate conversion breaks equality and unables to disconnect from event but is appears to solve the problem of covariance and contravariance in context of multicast delegates.
You first need a helper method:
public static class DelegateExtensions
{
public static Delegate ConvertTo(this Delegate self, Type type)
{
if (type == null) { throw new ArgumentNullException("type"); }
if (self == null) { return null; }
if (self.GetType() == type)
return self;
return Delegate.Combine(
self.GetInvocationList()
.Select(i => Delegate.CreateDelegate(type, i.Target, i.Method))
.ToArray());
}
public static T ConvertTo(this Delegate self)
{
return (T)(object)self.ConvertTo(typeof(T));
}
}
When you have a delegate:
public delegate MyEventHandler(T arg);
You can use it while combining delegates simply by converting a delegate do desired type:
MyEventHandler handler = null;
handler += new MyEventHandler(c => Console.WriteLine(c)).ConvertTo>();
handler += new MyEventHandler
It supports also disconnecting from event the same way, by using ConvertTo() method.
Unlike using some custom list of delegates, this solution provides thread safety out of the box.
Complete code with some samples you can find here: http://ideone.com/O6YcdI