IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

ASP.NET Discussion :

Expression Lambda et integer [Débutant]


Sujet :

ASP.NET

  1. #1
    Membre éprouvé
    Avatar de Pelote2012
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2008
    Messages
    925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2008
    Messages : 925
    Billets dans le blog
    2
    Par défaut Expression Lambda et integer
    Bonjour

    Mon but est de faire un tri sur une propriété de ma classe Eleve choisi de manière dynamique , ici défini en dur par sortPropertyName.

    Code vb : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
                Dim personType As Type = GetType(Eleve)
                Dim sortPropertyName As String = "Toto"
     
                If (personType.GetProperties().Any(Function(prop) prop.Name = sortPropertyName AndAlso prop.CanRead)) Then
                    Dim pinfo As PropertyInfo = personType.GetProperty(sortPropertyName)
                    Dim paramExpr As ParameterExpression = Expression.Parameter(GetType(Eleve), "instance")
                    Dim memberExpr As MemberExpression = Expression.Property(paramExpr, pinfo)
     
                    Dim orderByFunc As Func(Of Eleve, Object) = Expression.Lambda(Of Func(Of Eleve, Object))(memberExpr, paramExpr).Compile()
     
                    Dim sortFunc As Func(Of IEnumerable(Of Eleve), IOrderedEnumerable(Of Eleve)) = Nothing
     
                    If (Sens) Then
                        sortFunc = (Function(source) source.OrderBy(orderByFunc))
                    Else
                        sortFunc = (Function(source) source.OrderByDescending(orderByFunc))
                    End If
     
                    query = sortFunc(query).ToList()
                End If

    Ce code fonctionne nickel pour les strings mais pour les integer j'ai une erreur sur
    Code VB : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim orderByFunc As Func(Of Eleve, Object) = Expression.Lambda(Of Func(Of Eleve, Object))(memberExpr, paramExpr).Compile()
    Une expression de type 'System.Int32' ne peut pas être utilisée pour un type de retour 'System.Object'
    Comme j'ai du mal à comprendre le code (trouver à force de recherche Google), je ne comprend pas comment résoudre le problème.

    Merci de votre aide

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Int32 est un type valeur (struct). Quand tu affectes un type valeur à un object, par exemple comme ça :

    Code VB.NET : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Function Foo() As Object
        Return 42
    End Function
    Il se produit un "boxing" : ça crée un object qui contient la valeur. En IL ça donne ça :
    Code IL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ldc.i4.s    2A 
    box         System.Int32
    ret

    Le compilateur le fait implicitement, mais quand tu construis une méthode avec des expressions Linq, il faut ajouter manuellement la conversion en object:


    Code VB.NET : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
                Dim personType As Type = GetType(Eleve)
                Dim sortPropertyName As String = "Toto"
     
                If (personType.GetProperties().Any(Function(prop) prop.Name = sortPropertyName AndAlso prop.CanRead)) Then
                    Dim pinfo As PropertyInfo = personType.GetProperty(sortPropertyName)
                    Dim paramExpr As ParameterExpression = Expression.Parameter(GetType(Eleve), "instance")
                    Dim memberExpr As Expression = Expression.Property(paramExpr, pinfo)
                    If pinfo.PropertyType.IsValueType Then
                        memberExpr = Expression.Convert(memberExpr, GetType(Object))
                    End If
     
                    Dim orderByFunc As Func(Of Eleve, Object) = Expression.Lambda(Of Func(Of Eleve, Object))(memberExpr, paramExpr).Compile()
     
                    Dim sortFunc As Func(Of IEnumerable(Of Eleve), IOrderedEnumerable(Of Eleve)) = Nothing
     
                    If (Sens) Then
                        sortFunc = (Function(source) source.OrderBy(orderByFunc))
                    Else
                        sortFunc = (Function(source) source.OrderByDescending(orderByFunc))
                    End If
     
                    query = sortFunc(query).ToList()
                End If

  3. #3
    Membre éprouvé
    Avatar de Pelote2012
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2008
    Messages
    925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2008
    Messages : 925
    Billets dans le blog
    2
    Par défaut
    Merci pour l'explication.

    En reprenant ta modification
    Code vb.net : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    If pinfo.PropertyType.IsValueType Then
                        memberExpr = Expression.Convert(memberExpr, GetType(Object))
                    End If
    j'ai eu le message d'erreur :
    impossible de caster un type unaryExpression en MemberExpression
    En grattant j'ai trouvé ça

    Ce qui traduit donne :
    Code vb.net : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    If pinfo.PropertyType.IsValueType Then
                        memberExpr = CType(Expression.Convert(memberExpr, GetType(Object)).Operand, MemberExpression)
                    End If
    Mais au final je retrouve la même erreur

    Je pense que l'erreur est plus sur le "Object" de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Expression.Lambda(Of Func(Of Eleve, Object))(memberExpr, paramExpr).Compile()
    j'ai vu une fonction
    Code vb.net : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     Public Shared Function GetCorrectPropertyName(Of T) _
                    (ByVal expression As Expression(Of Func(Of T, Object))) As String
            If TypeOf expression.Body Is MemberExpression Then
                Return DirectCast(expression.Body, MemberExpression).Member.Name
            Else
                Dim op = (CType(expression.Body, UnaryExpression).Operand)
                Return DirectCast(op, MemberExpression).Member.Name
            End If
        End Function
    Mon instinct dit pas mal, mais je ne vois pas l'adaptation

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par Pelote2012 Voir le message
    En reprenant ta modification
    Code vb.net : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    If pinfo.PropertyType.IsValueType Then
                        memberExpr = Expression.Convert(memberExpr, GetType(Object))
                    End If
    j'ai eu le message d'erreur :
    Parce que tu n'as pas repris toute ma modification
    J'ai modifié le type de déclaration de la variable memberExpr en Expression (au lieu de MemberExpression), et là ça passe

  5. #5
    Membre éprouvé
    Avatar de Pelote2012
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2008
    Messages
    925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2008
    Messages : 925
    Billets dans le blog
    2
    Par défaut
    En plus t'as raison lol
    Mon nom de famille c'est LEBORGNE

    Pardon +50

    Sinon j'ai vu que
    Code vb.net : Sélectionner tout - Visualiser dans une fenêtre à part
     Dim orderByFunc As Func(Of WebForm2.Eleve, Integer) = Expression.Lambda(Of Func(Of WebForm2.Eleve, Integer))(memberExpr, paramExpr).Compile()
    marche pour les integer ... mais je préfère ta méthode, ça fait tout au lieu de m'embarquer dans un if elseif ... pour chaque type à problème

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 22/03/2011, 14h50
  2. Réponses: 2
    Dernier message: 09/08/2010, 15h41
  3. expression lambda evaluee qu'une seule fois
    Par vandamme dans le forum Boost
    Réponses: 10
    Dernier message: 17/12/2009, 14h49
  4. Décortiquer une expression lambda
    Par anthyme dans le forum Framework .NET
    Réponses: 4
    Dernier message: 17/12/2009, 12h57
  5. Réponses: 0
    Dernier message: 22/12/2008, 16h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo