C# 3.0 Return Type Inference Does Not Work On Method Groups

UPDATE: A lot of people have linked to this article which is somewhat out of date now. This article describes why in C# 3.0, return type inference does not work when the argument is a method group and the formal parameter is a generic delegate. As you can see, there was a lot of feedback…

17

Covariance and Contravariance in C#, Part Nine: Breaking Changes

Today in the last entry in my ongoing saga of covariance and contravariance I’ll discuss what breaking changes adding this feature might cause. Simply adding variance awareness to the conversion rules should never cause any breaking change. However, the combination of adding variance to the conversion rules and making some types have variant parameters causes…

34

Covariance and Contravariance in C#, Part Eight: Syntax Options

As I discussed last time, were we to introduce interface and delegate variance in a hypothetical future version of C# we would need a syntax for it. Here are some possibilities that immediately come to mind. Option 1: interface IFoo<+T, -U> { T Foo(U u); } The CLR uses the convention I have been using so…

66

Covariance and Contravariance in C# Part Seven: Why Do We Need A Syntax At All?

Suppose we were to implement generic interface and delegate variance in a hypothetical future version of C#. What, hypothetically, would the syntax look like? There are a bunch of options that we could hypothetically consider. Before I get into options though, let’s be bold. What about “no syntax at all”? That is why not just…

21

Covariance and Contravariance in C#, Part Six: Interface Variance

Over the last few posts I’ve discussed how it is possible to treat a delegate as contravariant in its arguments and covariant in its return type. A delegate is basically just an object which represents a single function call; we can do this same kind of thing to other things which represent function calls. Interfaces,…

12

Covariance and Contravariance In C#, Part Five: Higher Order Functions Hurt My Brain

Last time I discussed how we could in a hypothetical future version of C# allow delegate types to be covariant in their return type and contravariant in their formal parameter types. For example, we could have a contravariant action delegate: delegate void Action< -A > (A a); and then have Action<Animal> action1 = (Animal a)=>{…

19

Covariance and Contravariance in C#, Part Four: Real Delegate Variance

In the last two posts I discussed the two kinds of variance that C# already has — array covariance and member-group-to-delegate conversion covariance (on return types) and contravariance (on formal parameter types). Today I want to generalize the latter kind of variance. In C# 3.0 today, even though it is legal to assign a typeless method…

8

Covariance and Contravariance in C#, Part Three: Method Group Conversion Variance

Last time I discussed how array covariance is broken in C# (and Java, and a number of other languages as well.) Today, a non-broken kind of variance supported by C# 2.0: conversions from method groups to delegates. This is a more complicated kind of variance, so let me spell it out in more detail. Suppose…

14

Covariance and Contravariance in C#, Part Two: Array Covariance

C# implements variance in two ways. Today, the broken way. Ever since C# 1.0, arrays where the element type is a reference type are covariant. This is perfectly legal: Animal[] animals = new Giraffe[10]; Since Giraffe is smaller than Animal, and “make an array of” is a covariant operation on types, Giraffe[] is smaller than…

20

Covariance and Contravariance in C#, Part One

I have been wanting for a long time to do a series of articles about covariance and contravariance (which I will shorten to “variance” for the rest of this series.) I’ll start by defining some terms, then describe what variance features C# 2.0 and 3.0 already support today, and then discuss some ideas we are…

23