C# 4.0: Covariance And Contravariance In Generics Made Easy
In my last post, I went through what is variance in .NET 4.0 and C# 4.0 in a rather theoretical way.
Now, I’m going to try to make it a bit more down to earth.
Given:
class Base { }class Derived : Base { }
Trace.Assert(typeof(Base).IsClass && typeof(Derived).IsClass && typeof(Base).IsGreaterOrEqualTo(typeof(Derived)));
-
Covariance
<br /> <pre class="code"><span style="color: blue">interface </span><span style="color: #2b91af">ICovariantIn</span><<span style="color: blue">out </span>T> { }</pre> <br /> <pre class="code"><span style="color: #2b91af">Trace</span>.Assert(<span style="color: blue">typeof</span>(<span style="color: #2b91af">ICovariantIn</span><<span style="color: #2b91af">Base</span>>).IsGreaterOrEqualTo(<span style="color: blue">typeof</span>(<span style="color: #2b91af">ICovariantIn</span><<span style="color: #2b91af">Derived</span>>)));</pre> <a href="http://11011.net/software/vspaste"></a> <br /></li>
-
Contravariance
<br /> <pre class="code"><span style="color: blue">interface </span><span style="color: #2b91af">IContravariantIn</span><<span style="color: blue">in </span>T> { }</pre> <a href="http://11011.net/software/vspaste"></a> <br /> <pre class="code"><span style="color: #2b91af">Trace</span>.Assert(<span style="color: blue">typeof</span>(<span style="color: #2b91af">IContravariantIn</span><<span style="color: #2b91af">Derived</span>>).IsGreaterOrEqualTo(<span style="color: blue">typeof</span>(<span style="color: #2b91af">IContravariantIn</span><<span style="color: #2b91af">Base</span>>)));</pre> <a href="http://11011.net/software/vspaste"></a> <br /></li>
-
Invariance
<br /> <pre class="code"><span style="color: blue">interface </span><span style="color: #2b91af">IInvariantIn</span><T> { }</pre> <a href="http://11011.net/software/vspaste"></a> <br /> <pre class="code"><span style="color: #2b91af">Trace</span>.Assert(!<span style="color: blue">typeof</span>(<span style="color: #2b91af">IInvariantIn</span><<span style="color: #2b91af">Base</span>>).IsGreaterOrEqualTo(<span style="color: blue">typeof</span>(<span style="color: #2b91af">IInvariantIn</span><<span style="color: #2b91af">Derived</span>>)) && !<span style="color: blue">typeof</span>(<span style="color: #2b91af">IInvariantIn</span><<span style="color: #2b91af">Derived</span>>).IsGreaterOrEqualTo(<span style="color: blue">typeof</span>(<span style="color: #2b91af">IInvariantIn</span><<span style="color: #2b91af">Base</span>>)));</pre> <a href="http://11011.net/software/vspaste"></a></li>
Where:
public static class TypeExtensions { public static bool IsGreaterOrEqualTo(this Type self, Type other) { return self.IsAssignableFrom(other); } }