Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Oh, the trouble I get myself in when I simply try to do something simple.</p> <p>It turns out that <a href="http://msdn.microsoft.com/en-us/library/dd233059.aspx" rel="nofollow noreferrer">C# 4 allows this sort of covariance</a>---sort of. First, I have to make Thing an interface and specify the "out" generic parameter:</p> <pre><code>public interface Thing&lt;out T&gt; {...} </code></pre> <p>But if I do certain things, C# won't let me use covariance. For example, if I try to return T from the interface:</p> <pre><code>public interface Thing&lt;out T&gt; { public T GetT(); </code></pre> <p>Even if I manage to get covariance with Thing, what do I do with it?</p> <pre><code>Thing&lt;object&gt; thing=createThing(); </code></pre> <p>The compiler tells me that the type cannot be inferred from usage.</p> <p>Let's say I say screw the whole T thing and make the factory method return Thing of type object:</p> <pre><code>public static Thing&lt;object&gt; createThing() {...} </code></pre> <p>Fine, but now where do I put it?</p> <pre><code>IList&lt;Thing&lt;object&gt;&gt; list=new List&lt;Thing&lt;object&gt;&gt;(); Thing&lt;object&gt; thing=createThing(); list.Add(thing); </code></pre> <p>Yes, I have to say that this is a list of Thing with T of type Object, because C# has no wildcard type.</p> <p>If this were Java, I'd simply say:</p> <pre><code>public class Thing&lt;T&gt; {...} public static &lt;T&gt; Thing&lt;T&gt; createThing() {...} List&lt;?&gt; things=new ArrayList&lt;Thing&lt;?&gt;&gt;(); Thing&lt;?&gt; thing=createThing(); things.add(thing); </code></pre> <p>If I wanted extra safety by saying that T had to be of a special type, I'd say:</p> <pre><code>public static &lt;T extends MyBaseType&gt; Thing&lt;T&gt; createThing() {...} List&lt;? extends MyBaseType&gt; things=new ArrayList&lt;Thing&lt;? extends MyBaseType&gt;&gt;(); Thing&lt;? extends MyBaseType&gt; thing=createThing(); things.add(thing); </code></pre> <p>Then I'd figure out what T is later, when I had more information.</p> <p>This all seems to come down to incomplete generic covariance in C# coupled with the lack of C# generic wildcards. (I still maintain it isn't an erasure issue.)</p> <p>So what do I do? The only simple thing to do seems to follow Reinderien's answer and split out a non-generic base class.</p> <p>(I wonder if in this non-generic base class I could have object getValue() and then use covariance in the subclass to return T getValue()? Ack, I'm tired of this---I'll leave that for another day.)</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.
    1. VO
      singulars
      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