views:

166

answers:

4

Before C# 4.0 came out, I was quite excited about covariance and contravariance. It pandered to my fondness for theoretical correctness!

However, now that it’s out, and I’m back to writing normal, everyday, boring code, I’m starting to wonder: did I ever use it yet? And I notice that I haven’t used it consciously. None of the interfaces or delegates I have defined since have benefited from it.

There is only one single case in which I later discovered I unwittingly used covariance, but it’s very subtle and I could as well have not noticed it. Imagine X is a base-class and Y is a descendent of it:

if (enumerableOfYs.Contains(variableOfTypeX))

Are there any interesting or exciting examples where any of you guys have used covariance or contravariance in a real-life, non-contrived use-case and it has really saved the day by being spectacularly “correct”?

+1  A: 

Features like covariance and contravariance don't really "save the day." Rather, when used correctly, they make later maintenance easier. In this way, it's much like const correctness in C++. It doesn't add any power, but code written correctly uses it and it makes the system much easier to work with.

NOTE: I haven't used it yet because I just upgraded to VS 2010.

tster
Hm, I disagree. Const in C++ is a restriction. Covariance/contravariance is the opposite, it’s an extra ability.
Timwi
@Timwi, yes that's a good point. It does add a lot of value. I was wrong.
tster
A: 

I used C# for about three years, and I only recall ever "missing" variance features maybe once or twice.

It's possible that now that they're in the language, I'll find more opportunities to take advantage of them, but I do think they are 'minor' features at best.

(I'm interested to see what others answers appear here.)

Brian
+2  A: 

I viewed the excellent two-part video series on covariance and contravariance by Eric Lippert, one of the designers of the feature. The videos contain the clearest explanation I can find of how the feature works; however, the examples are contrived for the demonstration.

I especially appreciated Eric's discussion at the end of the second video about when he expected users would use the feature. He indicated that most line-of-business application developers probably would not create many interfaces employing covariance or contravariance, but that it is more likely the role of a framework developer (including your own frameworks, of course).

On the other hand, I can finally place an IEnumerable<DerivedClass> into a method expecting an IEnumerable<BaseClass> without jumping through type casting hoops myself. Eventually, I'll probably forget that I ever couldn't. I think this will be the most compelling and common usage of covariance/contravariance: super-subtle things that just work when, in earlier versions of .NET, they didn't.

kbrimington
+3  A: 

The only "real world" use of variance that I've run into in my actual writing-programs-for-customers (as opposed to writing compiler test cases or articles or whatever) is I now can pass an IEnumerable<TypeParameterDefinedInSource> to a method that expects an IEnumerable<TypeSymbol> when I write code analysis tools in C#.

It's really not a "save the day" sort of feature. It's more of a "it works the way I expect it to" feature.

Eric Lippert
Hi, Eric. Thanks for your answer. This leads me to a more general question though: How does the C# team prioritise features? How come that a feature that doesn’t “save the day” get so much more priority than features that would *both* “save the day” *and also* make things “work the way I expect them to”? (e.g. generic custom attributes, anonymous iterator blocks, etc.)
Timwi
@Timwi: We prioritize features based on a long list of competing criteria, including factors like difficulty of implementation, how well it works with or against other features, whether it fits into the broader theme for the release, and so on. Variance was easy; we knew how to implement it, it was already supported in the CLR, we understand the theory extremely well and it removed a genuine customer problem that is reported all the time. A larger feature would have taken away too many resources from making "dynamic" work which was the high order bit for the release.
Eric Lippert
I think "It's more of a "it works the way I expect it to" feature" is the key to way it is so useful.
Ian Ringrose