C#通过变量名获取和设置属性

有没有办法做到这一点? 我尝试测试对象的属性是否存在,如果存在,我想设置一个值。 (也许完整的想法很糟糕,如果是真的 – 为什么?)

class Info { public string X1{ set; get; } public string X2{ set; get; } public string X3{ set; get; } } Dictionary values = new Dictionary(); 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? } } 

是的,您正在寻找PropertyInfo.SetValue方法,例如

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

您需要在属性上调用SetValue方法:

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

我认为每次使用reflection都有点慢,所以,如果你不止一次进行初始化,你可以使用表达式树。 但每次你的字典应该具有与init相同的属性顺序。

可能的代码

 class Info { public string X1 { set; get; } public string X2 { set; get; } public int X3 { set; get; } private Action> initAction; public void Init(Dictionary 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)); ParameterExpression value = Expression.Variable(typeof(object)); ParameterExpression enumerator = Expression.Variable(typeof(IEnumerator)); var expList = new List(); 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>>(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; } } 

用法:

 var values = new Dictionary(); values.Add("X1", "blah1"); values.Add("X2", "blah2"); values.Add("X3", 8); Info info = new Info(); info.Init(values);