Arbres d&#39;expression dans .NET 4.0: Expression.Call ne parvient pas à trouver la méthode &quot;get_Item&quot; dans le type List <T>

.net-4.0 c# expression-trees lambda

Question

Je suis coincé avec le problème ci-dessous et je me demande si quelqu'un pourra vous aider. J'ai ajouté des commentaires au code pour le rendre explicite, mais laissez-moi savoir si vous avez besoin de plus d'informations ou si le problème n'est pas clair.

Merci beaucoup d'avance!

Edit: On m'a demandé de résumer le problème dans le texte. Le texte suivant: Dans les circonstances décrites dans le code ci-dessous, Expression.Call (...) lève l'exception suivante: "Aucune méthode 'get_Item' n'existe sur le type 'System.Collections.Generic.List`1 [System.Double]' "

Je crois que la méthode existe dans le type, comme indiqué ici:

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

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

J'ai également rendu le titre un peu plus descriptif; désolé si la question initiale n'était pas claire.

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: Je pense avoir trouvé une solution qui résout mon problème immédiat; en le publiant au cas où quelqu'un d'autre aurait du mal à le faire:

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

Réponse acceptée

La surcharge que vous utilisez concerne uniquement les méthodes statiques (voir la documentation: http://msdn.microsoft.com/en-us/library/bb351107.aspx ). Et "get_Item" n'est clairement pas une méthode statique. Donc, vous devez utiliser une surcharge de méthode différente. Essayez ceci, par exemple:

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



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi