0

I've recently run into an issue dealing with the contravariance of a function's parameters in C#, and how that isn't honored as soon as an Expression is wrapped around that function. Here's an example of what I'm talking about:

class BaseClass
{
    public bool IsSomething()
    {
        return true;
    }
}

class SubClass : BaseClass { }

static void Main(string[] args)
{
    // This works totally fine
    Func<BaseClass, bool> funcWithBaseClass = item => item.IsSomething();
    Func<SubClass, bool> funcWithSuperClass = funcWithBaseClass;
    var aValidCast = (Func<SubClass, bool>)funcWithBaseClass;

    Expression<Func<BaseClass, bool>> expressionWithBaseClass = item => item.IsSomething();
    // Expression<Func<SubClass, bool>> expressionWithSubClass = expressionWithBaseClass; Get a type mismatch error
    // var invalidCast = (Expression<Func<SubClass, bool>>)expressionWithBaseClass; Invalid cast exception
}

I figure the issue must stem from the fact that now the Func has itself become a generic type parameter.

Does anyone know how I could possibly circumvent this behavior?

Tom E.
  • 13
  • 5

1 Answers1

0

I figured out a way around this, if anyone's curious. I simply did something like this:

public static Expression<Func<SubClass,bool>> ConvertExpression(Expression<Func<BaseClass, bool>> baseClassExpression)
{
    Func<SubClass, bool> filterFunction = baseClassExpression.Compile(); // This assignment works because Func parameter types are contravariant.
    Expression<Func<SubClass, bool>> filterExpression = item => filterFunction(item);

    return filterExpression;
}
Tom E.
  • 13
  • 5