2017-09-22 9 views
0

Comment puis-je utiliser Expression pour définir des propriétés sur une instance d'un objet déjà existant? Je ne veux pas créer un nouvel objet, donc Expression.New où vous pouvez passer dans les initialiseurs de membres ne fonctionnera pas.Expression pour définir les propriétés d'une instance d'objet existante

Ceci n'est pas un doublon de How to set property value using Expressions? car cela prend un Expression et définit les propriétés via Reflection.

J'ai un existant object et je veux créer un Expression où je peux définir les propriétés. Cette expression sera ensuite compilée dans un delegate pour être exécutée.

+0

Possibilité de duplication de [Comment définir la valeur de la propriété à l'aide d'expressions?] (Https://stackoverflow.com/questions/9601707/how-to-set-property-value-using-expressions) –

+2

Expression.Assignment dans Expression. Propriété de votre objet (soit en tant que ConstantExpression ou ParameterExpression en fonction de la manière dont vous l'utilisez) en passant le PropertyInfo de la propriété que vous voulez affecter – pinkfloydx33

Répondre

1

Qu'en est:

public class User { 
    public string Name {get;set;} 
} 

public static void Main() 
{ 
    var user = new User(); 
    var assigner = GetAssigner<User, string>(u => u.Name); 
    assigner.Compile()(user, "Joe"); 
    Console.WriteLine(user.Name); 
} 

public static Expression<Action<TClass, TValue>> GetAssigner<TClass, TValue>(Expression<Func<TClass, TValue>> propertyAccessor){ 
    var prop = ((MemberExpression)propertyAccessor.Body).Member; 
    var typeParam = Expression.Parameter(typeof(TClass)); 
    var valueParam = Expression.Parameter(typeof(TValue)); 
    return Expression.Lambda<Action<TClass, TValue>>(
     Expression.Assign(
      Expression.MakeMemberAccess(typeParam, prop), 
      valueParam), typeParam, valueParam); 

} 

Rappelez-vous que l'expression est juste une définition de ce qui doit être fait, vous devez le compiler à un délégué de pouvoir l'invoquer.

+0

La combinaison de 'Expression.Assign' avec' Expression.MakeMemberAccess' est exactement ce que Je cherchais. –

1

Avez-vous envisagé d'utiliser MemberAssignment pour définir la valeur du (des) membre (s)?

Représente l'opération d'affectation pour un champ ou une propriété d'un objet.

Remarque importante dans les commentaires, cependant: vous ne pouvez pas les créer directement. Au lieu de cela,

Utilisez les méthodes usine Bind pour créer une affectation de membre. Une propriété MemberAssignment a la propriété BindingType égale à Assignment.

+0

J'ai une liste de 'MemberAssignment's. Comment puis-je créer une 'Expression' pour affecter ces objets à un objet existant? Je peux le faire en créant un nouvel objet via 'Expression.New', mais je ne sais pas comment le faire avec un objet existant. –

+0

Cela fait un moment, mais je crois me souvenir que 'MemberAssignment' est spécifique aux expressions d'initialisation d'objet, comme' new X {Member = y} '. Un simple 'Assign (Property (x," Member "), y),' devrait être bon. –

+0

Les documents ne mentionnent pas les expressions d'initialisation d'objet, vous pensez peut-être à [MemberInitExpression] (https://msdn.microsoft.com/en-us/library/system.linq.expressions.memberinitexpression (v = vs.110) .aspx)? –