Expression Trees in .NET 4.0: Expression.Call findet Methode &quot;get_Item&quot; in Typ List nicht <T>

.net-4.0 c# expression-trees lambda

Frage

Ich stecke mit dem unten stehenden Problem fest und frage mich, ob jemand da draußen helfen kann. Ich habe dem Code Kommentare hinzugefügt, um es selbsterklärend zu machen, aber lassen Sie es mich wissen, wenn Sie weitere Informationen benötigen oder wenn das Problem unklar ist.

Vielen Dank im Voraus!

Bearbeiten: Ich wurde gebeten, das Problem in Text zusammenzufassen, also hier geht es: unter den Umständen im folgenden Code, Expression.Call (...) löst die folgende Ausnahme aus: "Keine Methode 'get_Item' existiert für den Typ 'System.Collections.Generic.List`1 [System.Double]' "

Ich glaube, die Methode existiert in der Art, wie hier gezeigt:

List<double> sampleList = new List<double>();

Console.WriteLine(sampleList.GetType().GetMethod("get_Item") == null); // False

Ich habe den Titel auch etwas beschreibender gemacht; Entschuldigung, wenn die ursprüngliche Frage nicht klar war.

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?
    }
}

Edit: Ich denke, ich habe einen Workaround gefunden, der mein unmittelbares Problem löst; posten Sie es für den Fall, dass jemand anderes damit zu kämpfen hat:

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?
    }
}

Akzeptierte Antwort

Die Überladung, die Sie verwenden, ist nur für statische Methoden (siehe Dokumentation: http://msdn.microsoft.com/en-us/library/bb351107.aspx ). Und "get_Item" ist eindeutig keine statische Methode. Sie müssen also eine andere Methodenüberladung verwenden. Versuchen Sie dies zum Beispiel:

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



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum