我遇到了下面的问题,并且想知道是否有人可以提供帮助。我在代码中添加了注释,使其不言自明,但如果您需要更多信息或问题不清楚,请告诉我。
提前多多感谢!
编辑:我被要求在文本中总结问题,所以在这里:在下面的代码中描述的情况下,Expression.Call(...)抛出以下异常:“没有方法'get_Item'存在于类型'System.Collections.Generic.List`1 [System.Double]'“
上我相信该方法确实存在于类型中,如下所示:
List<double> sampleList = new List<double>();
Console.WriteLine(sampleList.GetType().GetMethod("get_Item") == null); // False
我也使这个标题更具描述性;抱歉,如果最初的问题不明确。
public class ExpressionExample
{
public void Main()
{
Expression<Func<List<double>, double>> component = u => u[0];
Console.WriteLine(component.Body.NodeType); // Prints out "Call"
Console.WriteLine(component.Body); // Prints out "u.get_Item(0)"
MethodCallExpression copyGetComponent = CopyCallExpression(component.Body as MethodCallExpression);
}
public MethodCallExpression CopyCallExpression(MethodCallExpression callExpression)
{
if (callExpression == null)
return null;
// Some tests
Console.WriteLine(callExpression.Method.Name); // "get_Item"
List<double> sampleList = new List<double>();
Console.WriteLine(sampleList.GetType().GetProperty("get_Item") == null); // True
Console.WriteLine(sampleList.GetType().GetProperty("Item") == null); // False
Console.WriteLine(sampleList.GetType().GetMethod("get_Item") == null); // False (1)
Console.WriteLine(sampleList.GetType().GetMethod("Item") == null); // True
Console.WriteLine(sampleList.GetType().FullName == callExpression.Method.DeclaringType.FullName); // True! (2)
// However...
Type[] argTypes = (from argument in callExpression.Arguments select argument.Type).ToArray();
// Next line throws an exception: No method 'get_Item' exists on type 'System.Collections.Generic.List`1[System.Double]'
return Expression.Call(callExpression.Method.DeclaringType, callExpression.Method.Name, argTypes, callExpression.Arguments.ToArray());
// How does this come together with items (1) and (2) above?
}
}
编辑:我想我找到了解决我眼前问题的解决方法;发布以防万一其他人在努力解决这个问题:
public class ExpressionExample
{
public void Main()
{
Expression<Func<List<double>, double>> invokeProp = u => u[0];
Console.WriteLine(invokeProp); // u => u.get_Item(0)
Console.WriteLine(invokeProp.Body); // u.get_Item(0)
Console.WriteLine(invokeProp.Body.NodeType); // Call
Expression copyGetComponent = CopyCallExpression(invokeProp.Body as MethodCallExpression);
LambdaExpression copyInvokeProp = Expression.Lambda(copyGetComponent, invokeProp.Parameters);
Console.WriteLine(copyInvokeProp); // u => u.Item[0]
Console.WriteLine(copyInvokeProp.Body); // u.Item[0]
Console.WriteLine(copyInvokeProp.Body.NodeType); // Index
// Technically different expressions, but I suppose
// they should be "functionally equal" though
}
public Expression CopyCallExpression(MethodCallExpression callExpression)
{
if (callExpression == null)
return null;
MethodInfo info = callExpression.Method;
if (info.Name == "get_Item")
{
PropertyInfo propInfo = typeof(List<double>).GetProperty("Item");
return Expression.MakeIndex(callExpression.Object, propInfo, callExpression.Arguments);
}
if (info.IsStatic)
return Expression.Call(info, callExpression.Arguments);
Type[] argTypes = (from argument in callExpression.Arguments select argument.Type).ToArray();
return Expression.Call(info.DeclaringType, info.Name, argTypes, callExpression.Arguments.ToArray());
}
答案 0 :(得分:5)
您使用的重载仅适用于静态方法(请参阅文档:http://msdn.microsoft.com/en-us/library/bb351107.aspx)。而“get_Item”显然不是一种静态方法。 因此,您需要使用不同的方法重载。试试这个,例如:
return Expression.Call(callExpression.Object, callExpression.Method, callExpression.Arguments.ToArray());