Search code examples
c#genericsinheritancedelegatesgeneric-programming

Why does 'Func<IBase>' compile while 'Func<TGeneric> where TGeneric : IBase' doesn't?


Why is the following bloc wrong?

    public interface IBase { }
    public class ClassX : IBase
    {
    }

    public class ClassY
    {
        public static ClassX FunctionReturnX() { return new ClassX(); }
    }

    public class ClassZ<TGeneric> where TGeneric : IBase
    {
        Func<IBase> funcInterface = ClassY.FunctionReturnX; //Right

        Func<TGeneric> funcGeneric = ClassY.FunctionReturnX; //Wrong
    }

Solution

  • In summary, you cannot cast ClassX to any class that implement IBase. You are only guaranteed to be able to cast it to IBase itself. Consider this example:

    Imagine that you have a class ClassA that implements IBase like this:

    public class ClassA : IBase
    {
    
    }
    

    Now, ClassZ<ClassA> would look like this (this is not real code):

    public class ClassZ<ClassA>
    {
        Func<IBase> funcInterface = ClassY.FunctionReturnX; //Right
    
        Func<ClassA> funcGeneric = ClassY.FunctionReturnX; //Wrong
    }
    

    ClassY.FunctionReturnX returns ClassX which you can cast to IBase, but you cannot cast it to ClassA. Therefore, you get the complication error.