更新:这个问题被标记为重复,但虽然我理解代码的问题,但我没有解决方案。代码是否可以通过仅更改方法主体而不是方法签名来工作?
我想在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>>'
代码是否可以通过仅更改方法主体而不是方法签名来工作?
更新:这个问题被标记为重复,但是尽管我理解代码的问题,但是我没有解决方案。代码是否可以通过仅更改方法主体而不是方法签名来工作?
是的,您可以保留方法签名,但您必须重写表达式...
像这样:
public void AddExpression<T1, T2>(Expression<Func<T1, T2>> e)
{
var originalParameter = e.Parameters[0];
// object par1
var parameter = Expression.Parameter(typeof(object), originalParameter.Name);
// T1 var1
var variable = Expression.Variable(typeof(T1), "var1");
// (T1)par1
var cast1 = Expression.Convert(parameter, typeof(T1));
// var1 = (T1)par1;
var assign1 = Expression.Assign(variable, cast1);
// The original body of the expression, with originalParameter replaced with var1
var body = new SimpleParameterReplacer(originalParameter, variable).Visit(e.Body);
// (object)body (a cast to object, necessary in the case T2 is a value type. If it is a reference type it isn't necessary)
var cast2 = Expression.Convert(body, typeof(object));
// T1 var2; var1 = (T1)par1; (object)body;
// (the return statement is implicit)
var block = Expression.Block(new[] { variable }, assign1, cast2);
var e2 = Expression.Lambda<Func<object, object>>(block, parameter);
_expressions.Add(e2);
}
我正在使用SimpleParameterReplacer
我前段时间给出的另一个回复。
最后 a (T1 x) => x.Something
(与x.Something
a T2
)被转换为:
(object x) =>
{
var var1 = (T1)x;
return (object)var1.Something;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句