簡體   English   中英

.NET 4.0中的表達式樹:Expression.Call在類型List中找不到方法“ get_Item” <T>

[英]Expression Trees in .NET 4.0: Expression.Call fails to find method “get_Item” in type List<T>

我遇到了以下問題,想知道是否有人可以提供幫助。 我已經在代碼中添加了注釋,以使其易於說明,但是如果您需要更多信息或問題尚不清楚,請告訴我。

在此先多謝!

編輯:我被要求以文本形式概括問題,因此,問題就解決了:在下面的代碼描述的情況下,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());
    }

您使用的重載僅適用於靜態方法(請參閱文檔: http : //msdn.microsoft.com/zh-cn/library/bb351107.aspx )。 而且“ get_Item”顯然不是靜態方法。 因此,您需要使用其他方法重載。 試試這個,例如:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM