C#, Using self as a parameter for an abstract override method of the base class

How would I override DerivedZ() in the child, without having to specify a U in the base class? The latter solution appears a bit excessive.

public abstract class Z {}
public class DerivedZ : Z 
{
    public DerivedZ (B someB, int num)
    {
        // initialize here
    }
}

// will not compile
// error: 'B.GetZ(B, int)': no suitable method found to override
// error: 'B' does not implement inherited abstract member 'A<DerivedZ>.GetZ(A<DerivedZ>, int)'
public abstract class A<T> where T : Z
{
    public abstract T GetZ (A<T> inputA, int optional=1);
}

public class B : A<DerivedZ>
{       
    public override DerivedZ GetZ (B someB, int optional=1)
    {
        return new DerivedZ (someB, optional)
    }
}

this works though...

public abstract class A<T,U> where T : Z where U : A<T,U>
{
    public abstract T GetZ (U inputA, int optional=1);
}

public class B : A<DerivedZ,B>
{
    public override DerivedZ GetZ (B someB, int optional=1)
    {
        return new DerivedZ (someB, optional);
    }
}
Jon Skeet
people
quotationmark

You can't use the first form, because it's not properly overriding the method. If you could do that, imagine this code:

public class C : A<DerivedZ> {}

A<DerivedZ> x = new B();
x.GetZ(new C());

That should work fine, after all - A<T>.GetZ is just declared to accept an A<T>, and C is a A<DerivedZ>.

The approach you've shown is fine.

I agree that sometimes it would be useful to be able to say "something of the same type" but it's not part of the C# type system.

people

See more on this question at Stackoverflow