Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to apply a generic extension to a specific generic type?
    primarykey
    data
    text
    <p>Imagine i have an extension method that operates of an interface of abstract objects:</p> <pre><code>public static void BlowTheirWhoHoovers(this ICollection&lt;Image&gt; source) { ... } </code></pre> <p>This extension knows how to blow the who hoovers of a list of images.</p> <p><strong>Note</strong>:</p> <ul> <li>it's a list of <strong>Images</strong>, which is abstract. As long as the lists contain anything that descends from Image (e.g. <code>Bitmap</code>, <code>Metafile</code>, <code>PngImage</code>) the extension can handle it</li> <li><code>source</code> list can by any kind of list as long as it exposes <code>ICollection</code></li> <li>since <code>source</code> list is going to potentially have items added or removed, it is <code>ICollection</code> rather than <code>IEnumeration</code> (<code>IEnumeration</code> doesn't support modifying the list)</li> </ul> <p>That's all well and good, except it doesn't work, the extension method is not found:</p> <pre><code>Collection&lt;Bitmap&gt; whoHonkers = new Collection&lt;Bitmap&gt;(); whoHonkers.BlowTheirWhoHoovers(); </code></pre> <p><img src="https://i.stack.imgur.com/LlMRo.png" alt="enter image description here"></p> <p>i assume this fails because: </p> <ul> <li>Visual Studio doesn't think <code>Collection</code> implements <code>ICollection&lt;T&gt;</code></li> <li>Visual Studio doesn't think <code>Bitmap</code> descends from <code>Image</code></li> </ul> <p>Now i <em>can</em> change my extension:</p> <pre><code>public static void BlowTheirWhoHoovers(this Collection&lt;Bitmap&gt; source) { ... } </code></pre> <p>which <em>does</em> compile:</p> <p><img src="https://i.stack.imgur.com/JLDIR.png" alt="enter image description here"></p> <p>except it's no longer useful (it requires <code>Collection</code>, and it requires <code>Bitmap</code>), e.g. it fails to work on anything except <code>Collection&lt;T&gt;</code>:</p> <pre><code>List&lt;Bitmap&gt; whoHonkers = new List&lt;Bitmap&gt;(); whoHonkers.BlowTheirWhoHoovers(); </code></pre> <p>It also fails on anything that it's <code>Bitmap</code>:</p> <pre><code>List&lt;Metafile&gt; whoHonkers = new List&lt;Metafile&gt;(); whoHonkers.BlowTheirWhoHoovers(); </code></pre> <p>or </p> <pre><code>List&lt;PngImage&gt; whoHonkers = new List&lt;PngImage&gt;(); whoHonkers.BlowTheirWhoHoovers(); </code></pre> <p>How can i apply an extension to anything that <strong>is</strong>:</p> <pre><code>ICollection&lt;Image&gt; </code></pre> <p>?</p> <p>i can't force anyone to change their declaration, e.g.:</p> <pre><code>List&lt;Bitmap&gt; </code></pre> <p>to</p> <pre><code>Collection&lt;Image&gt; </code></pre> <p><strong>Update</strong>:</p> <p>Possible avenues of solution exploration: </p> <ul> <li>finding the syntax that allows extensions on things that the compiler should be able to do</li> <li>manually casting the list; doing the compiler's job for it</li> </ul> <p><strong>Update#2</strong>:</p> <p>i could have simplified some of the distractions around <code>ICollection</code>, and made it <code>IEnumerable</code> (since it's a hypothetical example i can make up whatever i want). But the screenshots already show <code>Collection</code>, so i'm going to leave it as it is.</p> <p><strong>Update#3</strong>: </p> <p>As <a href="https://stackoverflow.com/a/8658578/12597">foson pointed out</a>, changing it to <code>IEnumerable</code> allows a way to cheat the answer. So it definitely should stay as <code>ICollection</code>.</p>
    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.
    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