2012-08-06 12 views
11

Esiste un modo per farlo? Provo a verificare se esiste una proprietà di un oggetto e se lo fa, voglio impostarne un valore. (Forse l'idea completa è male, se è vero - perché?)C# ottiene e imposta la proprietà in base al nome della variabile

class Info 
{ 
    public string X1{ set; get; } 
    public string X2{ set; get; } 
    public string X3{ set; get; } 
} 

Dictionary<string, string> values = new Dictionary<string, string>(); 
values.Add("X1","blah1"); 
values.Add("X2","blah2"); 
values.Add("NotThere","blah3"); 

Info info = new Info(); 

foreach (var item in values) 
{ 
    string propertyName = item.Key; 
    string value = item.Value; 
    if (info.GetType().GetProperty(propertyName) != null) //this probably works 
    { 
     info.propertyName = value; //this doesn't, how to set it? 
    } 
} 
+0

Se si sta facendo un sacco di questo, si consiglia di utilizzare uno strumento ottimizzato come [FastMember] (http://nuget.org/pacchetti/FastMember) –

risposta

28

Sì, la vostra ricerca per il metodo PropertyInfo.SetValue esempio

var propInfo = info.GetType().GetProperty(propertyName); 
if (propInfo != null) 
{ 
    propInfo.SetValue(info, value, null); 
} 
3

È necessario richiamare il metodo SetValue sulla proprietà:

var property = info.GetType().GetProperty(propertyName); 
if (property != null) 
{ 
    property.SetValue(info, value, null); 
} 
6
var propertyInfo = info.GetType().GetProperty(propertyName); 
if (propertyInfo != null) //this probably works. Yes it is 
    { 
     propertyInfo.SetValue(info, value, null); 
    } 
1

Penso che utilizzando la riflessione ogni volta è un po 'lento, quindi, se si fa che l'inizializzazione più di una volta che si può usare Expression Tree. Ma ogni volta il tuo dizionario dovrebbe avere lo stesso ordine di proprietà da avviare.

codice possibile

class Info 
{ 
    public string X1 { set; get; } 
    public string X2 { set; get; } 
    public int X3 { set; get; } 
    private Action<Info, List<object>> initAction; 

    public void Init(Dictionary<string, object> initDict) 
    { 
     //on first usage we deal with reflection and build expression tree to init properties 
     if (initAction==null) 
     { 
      ParameterExpression targetInstanceExpression = Expression.Parameter(this.GetType()); 
      ParameterExpression valuesExpression = Expression.Parameter(typeof(List<object>)); 
      ParameterExpression value = Expression.Variable(typeof(object)); 
      ParameterExpression enumerator = Expression.Variable(typeof(IEnumerator)); 

      var expList = new List<Expression>(); 
      expList.Add(Expression.Assign(enumerator, Expression.TypeAs(Expression.Call(valuesExpression, "GetEnumerator", null),typeof(IEnumerator)))); 
      foreach (var initRecord in initDict) 
      { 
       Expression moveNextExp = Expression.Call(enumerator, "MoveNext", null); 
       expList.Add(moveNextExp); 
       Type type = initRecord.Value.GetType(); 
       expList.Add(Expression.Assign(value, Expression.PropertyOrField(enumerator, "Current"))); 
       Expression assignExp = GetPropAssigner(initRecord.Key, type, targetInstanceExpression, value); 
       expList.Add(assignExp); 
      } 
      Expression block = Expression.Block 
      (
       new[] { value, enumerator }, 
       expList 
      ); 
      //compile epression tree and get init action 
      initAction = Expression.Lambda<Action<Info, List<object>>>(block, targetInstanceExpression, valuesExpression).Compile(); 
     } 
     initAction(this, initDict.Values.ToList()); 
    } 
    //little method to create property assigner 
    public static Expression GetPropAssigner(string propName, Type type, 
     ParameterExpression targetInstanceExp, ParameterExpression valueExp) 
    { 
     MemberExpression fieldExp = Expression.PropertyOrField(targetInstanceExp, propName); 
     BinaryExpression assignExp = Expression.Assign(fieldExp, type.IsValueType ? Expression.Unbox(valueExp, type) : Expression.TypeAs(valueExp, type)); 
     return assignExp; 
    } 
} 

Usage:

var values = new Dictionary<string, object>(); 
      values.Add("X1", "blah1"); 
      values.Add("X2", "blah2"); 
      values.Add("X3", 8); 


Info info = new Info(); 
info.Init(values); 
Problemi correlati