2010-01-16 20 views
2

我被困在下面的問題中,想知道是否有人能夠提供幫助。我已經添加了對代碼的評論,使其不言自明,但讓我知道如果您需要更多信息或問題不清楚。.NET 4.0中的表達式樹:Expression.Call無法在類型列表中找到方法「get_Item」列表<T>

非常感謝!

編輯:我被要求總結在文本中的問題,所以這裏它:在下面的代碼描述的情況下,Expression.Call(...)拋出以下異常:「No method'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

你能在文中簡要描述確切的問題是什麼(而不是在代碼註釋中描述它)嗎?你期待什麼,結果如何? – Eilon 2010-01-16 23:49:40

+0

簡而言之,Expression.Call將引發以下異常:「System.Collections.Generic.List'1 [System.Double]'」類型中存在無方法'get_Item'。我相信這種方法確實存在於這種類型中。 – 2010-01-16 23:53:34

+0

我剛剛也將此添加到了問題描述中。 – 2010-01-17 00:06:57

回答

5

您使用過載僅適用於靜態方法(見文檔:http://msdn.microsoft.com/en-us/library/bb351107.aspx)。而「get_Item」顯然不是一個靜態方法。 所以,你需要使用不同的方法重載。試試這個,例如:

return Expression.Call(callExpression.Object, callExpression.Method, callExpression.Arguments.ToArray()); 
+0

官方說明:我將從現在開始將「初學者」標籤添加到我的問題中。 +1(很多謝謝)因爲麻煩回答這個「嘟嘟!」東西(應該在發佈之前更仔細地閱讀文檔)。 – 2010-01-19 01:42:23

+0

如果你問關於表達樹的問題,你絕對不是初學者:-)這是一個相當先進的話題。 – 2010-01-19 03:43:07

+0

@Sasha He *可能是Expression Trees的初學者)很高興在這個論壇上看到來自微軟和俄羅斯的女孩!華。 – serhio 2011-09-09 17:24:11

相關問題