How to check if `IEnumerable<T1>` covariant to `IEnumerable<T2>`?
<p>What is common rule to check if <code>IEnumerable&lt;T1&gt;</code> covariant to <code>IEnumerable&lt;T2&gt;</code> ?</p>

<p>I've made some experiments:</p>

<hr>

<p><strong>1.</strong></p>

<pre><code>Object Obj = "Test string";
IEnumerable&lt;Object&gt; Objs = new String[100];
</code></pre>

<p><em>Works because <code>IEnumerable&lt;out T&gt;</code> is covariant and <code>String</code> inherits <code>Object</code>.</em> </p>

<p><strong>2.</strong></p>

<pre><code>interface MyInterface{}
struct MyStruct:MyInterface{}
.....
Object V = new MyStruct();
Console.WriteLine(new MyStruct() is Object); // Output: True. 
IEnumerable&lt;Object&gt; Vs = new MyStruct[100]; // Compilation error here
</code></pre>

<p><em><code>MyStruct</code> is actually an <code>Object</code>, but it does not work because <code>Object</code> is reference type and <code>MyStruct</code> is value type. OK, I see some logic here.</em></p>

<p><strong>3.</strong></p>

<pre><code>Console.WriteLine(new MyStruct() is ValueType); // Output: "True"
ValueType V2 = new MyStruct();
IEnumerable&lt;ValueType&gt; Vs2 = new MyStruct[100]; // Compilation error here
</code></pre>

<p><em>Should work because <code>IEnumerable&lt;out T&gt;</code> is covariant and <code>MyStruct</code> IS <code>ValueType</code>, but does not work... OK, maybe <code>MyStruct</code> does not actually inheritst <code>ValueType</code>....</em></p>

<p><strong>4.</strong></p>

<pre><code>MyInterface V3 = new MyStruct(); 
Console.WriteLine(V3 is MyInterface); // Output: "True" 
IEnumerable&lt;MyInterface&gt; Vs3 = new MyStruct[100]; // Compilation error here
</code></pre>

<p><em>Even this way: "Cannot convert MyStruct to MyInterface". Oh, really?? You just did it one line before...</em></p>

<hr>

<p>I've tried to formulate common rule:</p>

<pre><code>public static bool IsCovariantIEnumerable(Type T1, Type T2  ){          
    return (T2.IsAssignableFrom(T1)) &amp;&amp; !T2.IsValueType; // Is this correct??
}
</code></pre>

<hr>

<p>So, questions is how to actually determine if <code>IEnumerable&lt;T1&gt;</code> covariant to <code>IEnumerable&lt;T2&gt;</code>? Is my <code>IsCovariantIEnumerable(...)</code> function correct? If yes, is there any simplier way to check it? If not, how to fix it?</p>

<p><em>See also these articles: <a href="https://stackoverflow.com/questions/2033912/c-sharp-variance-problem-assigning-listderived-as-listbase">1</a>, <a href="https://stackoverflow.com/questions/12454794/why-covariance-and-contravariance-do-not-support-value-type">2</a>.</em></p>