Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><a href="https://stackoverflow.com/questions/26903/how-can-you-require-a-constructor-with-no-parameters-for-types-implementing-an#27386">Juan Manuel said:</a></p> <blockquote> <p>that's one of the reasons I don't understand why it cannot be a part of the contract in the interface</p> </blockquote> <p>It's an indirect mechanism. The generic allows you to "cheat" and send type information along with the interface. The critical thing to remember here is that the constraint isn't on the interface that you are working with directly. It's not a constraint on the interface itself, but on some other type that will "ride along" on the interface. This is the best explanation I can offer, I'm afraid.</p> <p>By way of illustration of this fact, I'll point out a hole that I have noticed in aku's code. It's possible to write a class that would compile fine but fail at runtime when you try to instantiate it:</p> <pre><code>public class Something : ITest&lt;String&gt; { private Something() { } } </code></pre> <p>Something derives from ITest&lt;T&gt;, but implements no parameterless constructor. It will compile fine, because String does implement a parameterless constructor. Again, the constraint is on T, and therefore String, rather than ITest or Something. Since the constraint on T is satisfied, this will compile. But it will fail at runtime.</p> <p>To prevent <strong>some</strong> instances of this problem, you need to add another constraint to T, as below:</p> <pre><code>public interface ITest&lt;T&gt; where T : ITest&lt;T&gt;, new() { } </code></pre> <p>Note the new constraint: T : ITest&lt;T&gt;. This constraint specifies that what you pass into the argument parameter of ITest&lt;T&gt; <strong>must</strong> also <strong>derive</strong> from ITest&lt;T&gt;.</p> <p>Even so this will not prevent <strong>all</strong> cases of the hole. The code below will compile fine, because A has a parameterless constructor. But since B's parameterless constructor is private, instantiating B with your process will fail at runtime.</p> <pre><code>public class A : ITest&lt;A&gt; { } public class B : ITest&lt;A&gt; { private B() { } } </code></pre>
 

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