Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy can't a list of an interface type accept instances of an inheriting interface?
    primarykey
    data
    text
    <p>Given the following types:</p> <pre><code>public interface IPrimary{ void doBattle(); } // an ISecondary "is" an IPrimary public interface ISecondary : IPrimary { } // An implementation of ISecondary is also an IPrimary: internal class SecondaryImpl : ISecondary { // Required, since this is an IPrimary public void doBattle(){ } } </code></pre> <p>Why can I not do this? </p> <pre><code>List&lt;IPrimary&gt; list = new List&lt;ISecondary&gt;(); </code></pre> <p>This results in the following compilation error:</p> <blockquote> <p>Argument type 'System.Collections.Generic.List' is not assignable to parameter type 'System.Collections.Generic.List'</p> </blockquote> <p>I understand the error, and I realize there are workarounds. I just do not see any clear reason why this direct conversion is disallowed. The values contained in a list of <code>ISecondary</code>, should after all, be (by extension) values of type of <code>IPrimary</code>.Why then are <code>List&lt;IPrimary&gt;</code> and <code>List&lt;ISecondary&gt;</code> being interpreted as unrelated types?</p> <p><strong>Can anyone explain clearly the reasoning for C# being designed this way?</strong></p> <p><em>A slightly extended example:</em> I came across the issue when trying to do something similar to the following:</p> <pre><code>internal class Program { private static void Main(string[] args) { // Instance of ISecondary, and by extention, IPrimary: var mySecondaryInstance = new SecondaryImpl(); // This works as expected: AcceptImpl(mySecondaryInstance); // List of instances of ISecondary, which are also, // by extention, instances of IPrimary: var myListOfSecondaries = new List&lt;ISecondary&gt; {mySecondaryInstance}; // This, however, does not work (results in a compilation error): AcceptList(myListOfSecondaries); } // Note: IPrimary parameter: public static void AcceptImpl(IPrimary instance){ } // Note: List of type IPrimary: public static void AcceptList(List&lt;IPrimary&gt; list){ } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload