在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 本身已成为泛型类型参数。
有谁知道我怎么可能规避这种行为?
如果
有人好奇,我想出了解决这个问题的方法。我只是做了这样的事情:
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;
}