views:

348

answers:

3

What is the real reason for that limitation? Is it just work that had to be done? Is it conceptually hard? Is it impossible?

Sure, one couldn't use the type parameters in fields, because they are allways read-write. But that can't be the answer, can it?

The reason for this question is that I'm writing an article on variance support in C# 4, and I feel that I should explain why it is restricted to delegates and interfaces. Just to inverse the onus of proof.

Update: Eric asked about an example.

What about this (don't know if that makes sense, yet :-))

public class Lookup<out T> where T : Animal {
  public T Find(string name) {
    Animal a = _cache.FindAnimalByName(name);
    return a as T;
  }
}

var findReptiles = new Lookup<Reptile>();
Lookup<Animal> findAnimals = findReptiles;

The reason for having that in one class could be the cache that is held in the class itself. And please don't name your different type pets the same!

BTW, this brings me to optional type parameters in C# 5.0 :-)

Update 2: I'm not claiming the CLR and C# should allow this. Just trying to understand what led to that it doesnt.

+6  A: 

As far as I know, this feature isn't supported by CLR, so adding this would require significant work on the CLR side as well. I believe that co- and contra-variance for interfaces and delegates was actually supported on CLR before the version 4.0, so this was a relatively straightforward extension to implement.

(Supporting this feature for classes would be definitely useful, though!)

Tomas Petricek
You're right. Variance in generic type params of interfaces and delegates came with CLR 2.0 - just not in C#
Lars Corneliussen
+10  A: 

First off, as Tomas says, it is not supported in the CLR.

Second, how would that work? Suppose you have

class C<out T>
{ ... how are you planning on using T in here? ... }

T can only be used in output positions. As you note, the class cannot have any field of type T because the field could be written to. The class cannot have any methods that take a T, because those are logically writes. Suppose you had this feature -- how would you take advantage of it?

This would be useful for immutable classes if we could, say, make it legal to have a readonly field of type T; that way we'd massively cut down on the likelihood that it be improperly written to. But it's quite difficult to come up with other scenarios that permit variance in a typesafe manner.

If you have such a scenario, I'd love to see it. That would be points towards someday getting this implemented in the CLR.

UPDATE: See

http://stackoverflow.com/questions/2733346/why-isnt-there-generic-variance-for-classes-in-c-4-0/2734070#2734070

for more on this question.

Eric Lippert
Good question :) I remember a discussion between Anders and some Java compiler geek (sorry) at the Lang.NET last year, where the Java-guy asked for this feature. He seemed to knwo why he asked. But I can't remember. I thought of classes without state. I'll try to make something up in the question.
Lars Corneliussen
This would be definitely a nice feature for immutable data types such as `Tuple<T1, T2>`, but I agree that this isn't convincing enough for changing the CLR :-).
Tomas Petricek
A: 

The answer seems to be too simple: It's just not implemented in the CLR.

I can't say this is a satisfying answer, but the discussion seems dead.

Lars Corneliussen