Search code examples
c#genericsgeneric-method

Generic methods and type casting


I read the following question (and I would solve it the same way as the given answer): Passing derived type as argument to abstract class

But why is it not able to find the value attribute from the derived class? even if I add a type cast it is not possible:

public abstract class baseClass
{
    public abstract float function<T>(T a, T b) where T:baseClass;
}

public class derived: baseClass
{
    public override float function<derived>(derived a, derived b)
    {
        // Here value is not found
        return a.value + b.value;
    }

    public float value;
}

Example with type cast is also not working (and the advice redundant type cast is shown):

public abstract class baseClass
{
    public abstract float function<T>(T a, T b) where T:baseClass;
}

public class derived: baseClass
{
    public override float function<derived>(derived a, derived b)
    {
        // Here value is not found even with type cast
        return ((derived)a).value + ((derived)b).value;
    }

    public float value;
}

Solution

  • Because you're declaring the generic type parameter on the method. The compiler doesn't understand that this should be of the derived type. All it knows it that you've introduced a new generic type parameter.

    What you want is called F-bound polymorphism, where the type parameter is of the implementing class, defined recursively:

    public abstract class BaseClass<T> where T : BaseClass<T>
    {
        public abstract float Function(T a, T b);
    }
    
    public class Derived : BaseClass<Derived>
    {
        public override float Function(Derived a, Derived b)
        {
            return a.Value + b.Value;
        }
    
        public float Value { get; set; }
    }