Home > C# 4.0, delegates > That Unfortunate Interaction Between Multicast Delegates and Contravariance in C# 4.0

That Unfortunate Interaction Between Multicast Delegates and Contravariance in C# 4.0

About seven months ago, a little while after VS2010 Beta 1 came out, I was thinking about events, and to what extent the typical eventing pattern in .NET is necessary or unnecessary. Would it be okay to use Action as the delegate type, for example?

This led me to thinking about how multicast delegates are immutable lists, and the += operator therefore works on them in the same way as that overloaded operator would normally work in C#, i.e. it expands to d1 = d1 + d2. This means that if d1 and d2 are different types but are assignment-compatible due to the new contravariance rules in C#4, the CLR (which does all the multicast work) has to decide what the type of the new delegate list will be. Curious to find out how this was resolved, I wrote a quick test program, ran it in the beta, and found that it hadn’t been.

And I just noticed that last week another sighting cropped up on Stack Overflow.

I don’t think it’s a very big deal, though. It’s an edge case. Okay, it means that the compiler allows you to compile a program with no casts which contains a runtime type error, but it’s not the first such case, or even the second.

The variance feature is quite brilliant, regardless. It’s easy to avoid this problem. The default choices made by most developers will already avoid it. EventHandler is not enabled for contravariance, and that is what events tend to be defined by, so no major problem there.

Also if you really need multicasting with Action delegates, a “safe” version can be implemented via a generic library solution, e.g. some extension methods like this:

public static Action<TArg1> ToMulticast<TArg1>(
    this IEnumerable<Action<TArg1>> actions)
{
    return arg1 =>
    {
        foreach (var action in actions)
            action(arg1);
    };
}

// and so on for up to 8 arguments...

This implementation works fine because it avoids the CLR’s Delegate.Combine. It has the same limitation as Action in that you can’t have ref or out parameters. (If you desperately want a language that has support for that kind of thing, you need (a) C++0x and (b) to rethink your priorities.)

In any case, there will soon be a much more fashionable way to broadcast events to several recipients.

About these ads
Categories: C# 4.0, delegates Tags: ,
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: