在Expression中,TDelegate的参数不是逆变的

本文关键字:TDelegate 参数 Expression | 更新日期: 2023-09-27 18:35:29

>我最近遇到了一个问题,涉及 C# 中函数参数的逆变性,以及一旦表达式被包裹在该函数周围,它就不会得到尊重。以下是我所说的一个例子:

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
}

我认为问题必须源于这样一个事实,即现在 Func 本身已成为泛型类型参数。

有谁知道我怎么可能规避这种行为?

在Expression<TDelegate>中,TDelegate的参数不是逆变的

如果

有人好奇,我想出了解决这个问题的方法。我只是做了这样的事情:

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;
}