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

Framework .NET Discussion :

Décortiquer une expression lambda


Sujet :

Framework .NET

  1. #1
    Membre éprouvé Avatar de anthyme
    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    1 559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 559
    Points : 1 257
    Points
    1 257
    Par défaut Décortiquer une expression lambda
    Bonjour,

    J'aimerai "décortiquer" une expression lambda pour récupérer certaine valeurs

    Par exemple si je reçoit une expression lambda de ce type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class User
    {
    public string Name {get;set;}
    public string Mail {get;set;}
    }
     
    Func<User, bool> expression = u => u.Name == "Toto" && u.Mail == "toto@gmail.com";
    J'aimerai pouvoir faire cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    User u = new User();
    u.Name = <manipulation sur mon expression pour obtenir "Toto">;
    u.Mail = <manipulation sur mon expression pour obtenir "toto@gmail.com">;
    (D'ailleurs le choix de faire une affectation de u.Name devrait aussi dépendre d'une "détection" sur mon expression)

    Est ce que vous savez comment je pourrais faire cela ?

    merci

  2. #2
    Membre expérimenté Avatar de davcha
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 258
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 258
    Points : 1 539
    Points
    1 539
    Par défaut
    Inspires-toi de ça :
    Code c# : 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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    using System;
    using System.Collections.Generic;
    using System.Linq.Expressions;
    using System.Reflection;
     
    namespace ConsoleApplication1
    {
    	class User
    	{
    		public string Name { get; set; }
    		public string Mail { get; set; }
    	}
     
    	class Program
    	{
    		static T convert<T>(Expression<Func<T, bool>> e)
    			where T : class, new()
    		{
    			Expression body = Expression.MemberInit(
    				Expression.New(typeof(T)),
    				getBindings(e));
    			LambdaExpression ctor = Expression.Lambda(body);
    			Func<T> f = ( Func<T> )ctor.Compile();
    			return f();
    		}
     
    		static IEnumerable<MemberBinding> getBindings<T>(Expression<Func<T, bool>> e)
    		{
    			LambdaExpression lambda = ( LambdaExpression )e;
    			return explore(lambda.Body);
    		}
     
    		static IEnumerable<MemberBinding> explore(Expression e)
    		{
    			BinaryExpression b = ( BinaryExpression )e;
    			MemberInfo mi = null;
    			Expression value = null;
    			if ( b.NodeType == ExpressionType.Equal ) {
    				if ( b.Left.NodeType == ExpressionType.MemberAccess )
    					mi = (( MemberExpression )b.Left).Member;
    				else if ( b.Left.NodeType == ExpressionType.Constant )
    					value = b.Left;
    				if ( b.Right.NodeType == ExpressionType.MemberAccess )
    					mi = (( MemberExpression )b.Right).Member;
    				else if ( b.Right.NodeType == ExpressionType.Constant )
    					value = b.Right;
    				yield return Expression.Bind(mi, value);
    			} else {
    				foreach ( var m in explore(b.Left) )
    					yield return m;
    				foreach ( var m in explore(b.Right) )
    					yield return m;
    			}
    		}
     
    		static void Main(string [] args)
    		{
    			var user = convert((User u) => u.Name == "Toto" && u.Mail == "toto@gmail.com");
    		}
    	}
    }

  3. #3
    Membre éprouvé Avatar de anthyme
    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    1 559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 559
    Points : 1 257
    Points
    1 257
    Par défaut
    merci pour ce bout de code !
    Pour le moment ça ne marche pas car mes string sont stocké dans des variables
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    string key = "toto";
    var obj = convert(e => e.Name == key);
    Mais bon je devrais m en sortir je vais juste mettre comme convention que l'on utilise clef == valeur et non pas valeur == clef.

  4. #4
    Membre expérimenté Avatar de davcha
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 258
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 258
    Points : 1 539
    Points
    1 539
    Par défaut
    Juste par curiosité : qu'es-tu en train de faire, exactement ?

  5. #5
    Membre éprouvé Avatar de anthyme
    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    1 559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 559
    Points : 1 257
    Points
    1 257
    Par défaut
    J'etend mon pattern de repository pour y inclure une méthode "GetOrCreate"
    qui renvoi un l'objet répondant à la requête linq ou s'il n'existe pas le créé et le marque comme étant à ajouter en base (derrière c'est nhibernate qui prend le relai mais ça pourrait aussi être EF)

    Ce genre de design est tres itnéréssant avec des objet créé à la volé comme par exemple des tags sur un article

    on a un site web ou quelqu'un créé des articles et a comme sur blogger une zone de texte pour mettre ses tag ou il peut mettre par exemple "photo, vacance, Espagne"

    Ensuite dans l'appli y a plus qu'a faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    foreach(string tagName in tags)
    {
        myArticle.Tags.Add(tagsRepository.GetOrCreate(t=>t.Name == tagName));
    }

Discussions similaires

  1. [Débutant] passer d'un tableau à une liste dans une expression lambda
    Par Hepil dans le forum Linq
    Réponses: 8
    Dernier message: 25/06/2013, 17h23
  2. [Débutant] créer une expression lambda pour filtrer un tableau
    Par Hepil dans le forum Linq
    Réponses: 7
    Dernier message: 20/06/2013, 14h35
  3. Réponses: 11
    Dernier message: 01/12/2011, 15h53
  4. Réponses: 2
    Dernier message: 09/08/2010, 15h41
  5. expression lambda evaluee qu'une seule fois
    Par vandamme dans le forum Boost
    Réponses: 10
    Dernier message: 17/12/2009, 14h49

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