Note that there are some explanatory texts on larger screens.

plurals
  1. POC# generic method with interface type constraint
    primarykey
    data
    text
    <p>Let's assume I have:</p> <ul> <li>A generic method <code>Get&lt;T&gt;</code></li> <li>A few interfaces <code>IEntity</code>, <code>IValue</code></li> <li>A few classes that respectively implements those interfaces ex: <code>Entity</code> -> <code>IEntity</code>, <code>Value</code> -> <code>IValue</code> etc.</li> </ul> <p><strong>=> Is there a way for the <code>Get&lt;T&gt;</code> method to allow the interfaces only as generic Types?</strong></p> <pre><code>Get&lt;IEntity&gt;(42); //Allowed Get&lt;Entity&gt;(42); //Compiler error </code></pre> <p><strong>My current solution looks like this:</strong></p> <ul> <li>A generic method <code>Get&lt;T&gt;</code> with a Type constraint <code>where T: IPersistable</code> (to prevent most of the types to be passed as a parameter)</li> <li>The interfaces implement <code>IPersistable</code></li> </ul> <p>The function actively checks the type:</p> <pre><code>public T Get&lt;T&gt;(long id) where T : IPersistable { if (typeof (T) == typeof (IEntity)) return (T) EntityDao.Get(id); if (typeof (T) == typeof (IValue)) return (T) ValueDao.Get(id); //... throw new TechnicalException("Type not supported"); } </code></pre> <p>=> The problem are: </p> <ol> <li>It is not clean... I could live with that since there are only very few types to check from</li> <li>The signature does not match what the function really does. It allows an <code>IPersistable</code> in, but not really &lt;- <strong>that really bugs me :(</strong></li> </ol> <p><em>Edit</em>: I'm considering such constraints to avoid surpopulation of my class. </p> <p>I have something like 8 or 9 generic methods in that class that all pretty much work this way. The intuitive way of doing would be as @DanielHilgarth suggested to have 1 method per type only. The methods currently can be called with 4 or 5 types only. But still, that would mean 32-40 methods in that class.</p> <p>If possible I'd like to avoid that.</p> <p><em>Edit2</em>: the need for preventing "real" classes to be called comes from a covariance/contravariance problem. The EntityDao and ValueDao <code>Get&lt;T&gt;</code> methods return <code>IEntity</code> and <code>IValue</code> objects. What works fine when I query for a single object fails when I call for a collection in a <code>GetAll&lt;T&gt;</code> methods since I cannot cast an <code>IEnumerable&lt;IValue&gt;</code> in an <code>IEnumerable&lt;Value&gt;</code>.</p> <p>I just noticed <a href="https://stackoverflow.com/a/4931809/568074">this answer</a> from @JonSkeets about casting of lists. That could be a workaround...</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.
 

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