Note that there are some explanatory texts on larger screens.

plurals
  1. PO.Net generics -- implementation inheritance from interface
    primarykey
    data
    text
    <p>I have two sequences of objects 'A' and 'B'. Comparing the sequences should produce a third sequence 'C' of elements that indicate whether:</p> <ul> <li>the objects were "deleted" from 'A' or </li> <li>"inserted" from 'B'. </li> </ul> <p>All remaining elements are considered as "matched".</p> <h2>What I would like to do:</h2> <p>Declare <code>Inserted&lt;T&gt;</code>, <code>Deleted&lt;T&gt;</code>, and <code>Matched&lt;T&gt;</code> generic classes that inherit all their properties from the <code>T</code> base class. The generic class must be able to instantiate itself from the object it inherits. </p> <h2>The code:</h2> <pre><code>public interface IInstantiable&lt;T&gt; { void CopyFrom(T o); } [Serializable] public class Inserted&lt;T&gt; : T where T : IInstantiable&lt;T&gt; { public Inserted() { } public Inserted(T t) { this.CopyFrom(t); } } </code></pre> <h2>The error:</h2> <pre><code>'MyNamespace.Inserted&lt;T&gt;' does not contain a definition for 'CopyFrom' and no extension method 'CopyFrom' accepting a first argument of type 'MyNamespace.Inserted&lt;T&gt;' could be found (are you missing a using directive or an assembly reference?) </code></pre> <h2>Further discussion:</h2> <p>I define my own <code>IInstantiable</code> interface to enforce the existence of a <code>CopyFrom</code> method. I cannot use the standard <code>ICloneable</code> interface, because it only defines a method that copies the object to a new instance, whereas I need the object to copy its members in the constructor.</p> <p>The error goes away if the generic defines its own implementation of the <code>CopyFrom</code> method; however, this does not achieve the desired goal of specializing the <code>CopyFrom</code> method to handle the specific needs of the base class. Only the base class could know what properties should be copied. (Or am I missing something?)</p> <p><strong>Note</strong>: The final object should have the same public members as its base class, as the object should be capable of serialization.</p> <p>Is this possible in .NET?</p> <h2>The answer:</h2> <p>What I am attempting to do is impossible, simply because the generic class cannot be an extension of the template base class. Visual Studio complains "Cannot derive from 'T' because it is a type parameter." (I hadn't noticed this error yet because I had not implemented the <code>CopyFrom</code> method in the generic class yet.)</p> <p>If I were to change the interface into a class and supply a stub implementation in that class, I could inherit from it as suggested below; however, this introduces a new base class into my inheritance hierarchy.</p> <pre><code>public class IInstantiable&lt;T&gt; { public virtual void CopyFrom(T o) { } } [Serializable] public class Inserted&lt;T&gt; : IInstantiable&lt;T&gt; where T : IInstantiable&lt;T&gt; { public Inserted() { } public Inserted(T t) { base.CopyFrom(t); } } </code></pre> <p>Unfortunately, I cannot use this new base class in its templatized form because I must introduce it at the root of my inheritance hierarchy. It works only if I remove the template and make it as generic as possible.</p> <pre><code>public class IInstantiable { public virtual void CopyFrom(Object o) { } } </code></pre> <p>However, this still does not make my <code>Inserted&lt;T&gt;</code> generic look like the object it is initialized from, and since I cannot inherit from the same type as the type parameter, it does not suit my initial purpose. </p> <p>Moving away from "fancy generics" based on the type system to more (ahem) generic annotated structures might prove to be the best solution; however, the default behavior of my selected serialization approach (XmlSerialization) does not have the automatic support that would make this configuration a viable solution. Generics will not work; use hard-coded class definitions instead. </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.
 

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