Parcourir une expression Linq pour définir la valeur d'un champ de propriété

c# expression-trees linq

Question

C'est une question très compliquée même si cela semble simple. Je pense que je devrais parcourir l’arbre d’expression complet à moins que quelqu'un ne connaisse un meilleur moyen.

Disons que j'ai un objet utilisateur

class User
{
    public UserAccount Account {get;set;}
}
class UserAccount
{
    public Name {get;set;}
}
var user = new User() { Account = new UserAccount()};

Comment utiliser des expressions linq pour définir la propriété de Name

class User
{
    public UserAccount Account {get;set;}
}
class UserAccount
{
    public Name {get;set;}
}
var user = new User() { Account = new UserAccount()};

Réponse acceptée

Eh bien, vous ne devez pas seulement parcourir l’arbre d’expression: vous devez également convertir la propriété finale "getter" que vous rencontrez en une propriété "setter". Essentiellement, vous voudriez trouver l'expression qui agit comme la "cible" du getter (c'est-à-dire l'objet pour lequel elle va obtenir la propriété de), l'évaluer pour obtenir la cible, puis rechercher le setter correspondant pour la propriété finale, et appelez-le avec la cible et la nouvelle valeur.

Notez qu'en demandant uniquement à l'arbre des expressions de représenter le "getter", vous perdez une partie de la sécurité à la compilation à laquelle vous pourriez vous attendre ... car un appelant peut transmettre une propriété en lecture seule:

SetValue(c => c.Account.Name.Length, 0); // string.Length is read-only

Une autre alternative serait de changer votre code pour que l'expression lambda représente le configurateur à la place:

SetValue(c => c.Account.Name.Length, 0); // string.Length is read-only

Dans ce cas, vous n’auriez même pas besoin d’un arbre d’expression. Vous pouvez utiliser un simple délégué et l’exécuter correctement.

Malheureusement, vous ne nous avez pas vraiment donné suffisamment d'informations sur ce que vous essayez de faire pour savoir si cette suggestion est réalisable.


Réponse populaire

Oui, vous devrez parcourir l'intégralité de l'arbre des expressions, ce qui peut être difficile si vous souhaitez travailler dans le cas général. Ne pouvez-vous pas simplement faire ceci à la place:

SetValue<User>(c => c.Account.Name = "Test");

SetValue est défini comme ceci:

SetValue<User>(c => c.Account.Name = "Test");

Ou sans le paramètre générique si cela fonctionnera uniquement avec l' User .




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