【发布时间】:2017-03-22 21:55:09
【问题描述】:
更新:这个问题被标记为重复,但虽然我理解代码的问题,但我没有解决方案。代码是否可以仅通过更改方法体而不更改方法签名来工作?
在尝试构建类似以下的类时,我正试图围绕Expression 和Func 进行思考:
public class Test<TBase>
{
private IList<Expression<Func<object, object>>> _expressions = new List<Expression<Func<object, object>>>();
public void AddExpression<T>(Expression<Func<TBase, T>> e)
{
_expressions.Add(e);
}
public void AddExpression<T1, T2>(Expression<Func<T1, T2>> e)
{
_expressions.Add(e);
}
}
我需要/想要保留一个表达式列表,Func 中的类型可能会有所不同。我虽然上面的代码可以工作,但它没有。它失败了:
Cannot convert from 'Expression<Func<TBase, T>>' to 'Expression<Func<object, object>>'
Cannot convert from 'Expression<Func<T1, T2>>' to 'Expression<Func<object, object>>'
Resharper 说:
Argument type 'Expression<Func<TBase, T>>' is not assignable to parameter type 'Expression<Func<object, object>>'
Argument type 'Expression<Func<T1, T2>>' is not assignable to parameter type 'Expression<Func<object, object>>'
是否可以只更改方法体而不更改方法签名来使代码工作?
【问题讨论】:
-
Func<T, TResult>仅在TResult上是协变的,因为那是输出,但在T上是逆变的,因为那是输入。因此,如果您有一个Func<int, string>,则可以将string转换为object,但您不能只为int传递任何object。 msdn.microsoft.com/en-us/library/dd799517(v=vs.110).aspx -
非常类似于stackoverflow.com/q/42951537/613130,但增加了要求转换参数和返回值的复杂性。
标签: c# generics expression