Oct 30

One of the things that we’ll have in C# 4.0 is covariance/contravariace working on generics…I mean, sort of. Why do I say sort of? Well, because you’ll have to use the identifiers in and out for explicitly stating if you’ll be having covariance or contravariance and you can’t use them at the some time. Charlie Calvert has a good post on this subject, so you should read it before we go on.

Don’t get me wrong: having this basic support is better than having none, but I expected a little more from the C# team. I’m sure there’s a valid reason for making us use the in an out terms, but personally, I’d really prefer not to use any and let the damn thing be automatically infered. But to me that is not the worst part… what I really don’t like is that (and please tell me I’m wrong!) you cannot annotate a generic type with in and out simultaneously. In practice, this means that you should be able to use both features with simple interfaces (ex.: IEnumerable) but you won’t be able to use them withthe current collection interfaces because you’ll have cases where you want to use covariance and contravariance at the same time on a specific type…

btw, Eric Lippert has a great series on this topic.


Update: Ok, didn’t I said that Eric had a great series? Yes he does and he convinced me that we need to think about it explicitly. Not convinced about not being able to say that a parameter can be in and out at the same time…

6 comments so far

  1. Andrew Davey
    1:23 pm - 10-30-2008

    I think having both contra and co-variance at the same time defeats the point of either. You would lose the static type safety.
    However, List is IEnumerable is IEnumerable, so you can still do useful things by accessing a contra- or co-variance interface implemented by a class.
    I”ve not had a chance to play with C#4 yet, but it looks very promising.

  2. luisabreu
    1:29 pm - 10-30-2008

    Yes, I agree with you Andrew…
    Everytime I start looking at this I”m able to loose myself again and again…I”ll have to test it out with the compiler to see if some of the things I”m thiking work as I expect them too…

  3. Pavel Minaev
    7:12 am - 10-31-2008

    You cannot use “in” and “out” at the same time because they are mutually exclusive, by definition: “in” means that “this is only ever going to be used as an argument”, “out” means “this is only ever going to be used as a return value” (a bit more complicated, considering ref/out, but that”s the gist of it). It”s those restrictions that actually allow them to be treated covariantly and contravariantly. If your class uses a type parameter T in both ways, it”s inherently invariant, and there”s nothing that can be done about it.

  4. luisabreu
    9:15 am - 10-31-2008

    Yes, that is what generally happens. My only problem with it is that you cannot have the same generic type be covariant and contravariant at the same time. Here”s a method where I might need that:

    T Mymethod(T parameter)

    With the current release, I”ll need to declare it with 2 generic type arguments:

    R MyMethod(T parameter)

  5. Pavel Minaev
    2:30 pm - 10-31-2008

    > My only problem with it is that you cannot have the same generic type be covariant and contravariant at the same time.

    You cannot have that by the very definition of “covariant” and ”contravariant”, if you want to preserve type safety.

  6. luisabreu
    7:28 pm - 11-3-2008

    Pavel, yes and no. What I”m saying is that you need to declare 2 type arguments for having covariance and contravariance on that same type (no, I don”t want both of them at the same type on the same parameter ok:))