4 ms·
One of the features not listed here is a little talked about (or perhaps just overlooked by me) feature of 4.0, covariance and contravariance.[1] One of the an
by MatthewPhillips 15y ago
One of the features not listed here is a little talked about (or perhaps just overlooked by me) feature of 4.0, covariance and contravariance.[1] One of the annoying things I've always had to deal with on collection classes is knowing that an instance implements some interface (because it is where T : ISomeInterface) but having to cast the collection in methods. 4.0 fixes that with the <out T> directive. I still haven't completely wrapped my head around the concepts but they seem pretty powerful to me.
[1]http://msdn.microsoft.com/en-us/library/dd799517.aspx http://msdn.microsoft.com/en-us/library/dd799517.aspx
- tkellogg 15y agoIt took me a while to understand it because it requires you to think differently about methods & types. Basically, a method can have inputs (parameters) and outputs (return values). So if you have an interface: public void IEnumerable<T> { IEnumerator<T> GetEnumerator(); } The T type is only used in outputs in all the members. Therefore it can be declared with the `out` directive (i.e. public void IEnumerable<out T>). Covariance & contravariance doesn't work with classes, only with interfaces & delegates. Consider this delegate: public delegate void Action<in T>(T obj); This can be declared with covariance (the in directive) because it only uses T in it's inputs. So an Action<string> can be passed into a method that takes Action<object>. Also, note that this doesn't work with T Func<T>(T obj) because it takes T as input & returns it (output). However, it does work with TReturn Func<in T, out TReturn>(T obj) because neither T nor TReturn is taken as both input & output. Does this make more sense? It's a hard concept to fully understand