这就是我的意思:
我需要能够替换这个丑陋的C#代码:
if (attribute.Name == "Name") machinePool.Name = attribute.Value;
else if (attribute.Name == "Capabilities") machinePool.Capabilities = attribute.Value;
else if (attribute.Name == "FillFactor") machinePool.FillFactor = attribute.Value;
这样的事情:
machinePool.ConvertStringToObjectField(attribute.Name) = attribute.Value;
没有ConvertStringToObjectField()方法,但我希望有这样的东西,如果可能的话。我可以访问machinePool对象类代码,所以我可以添加必要的代码,但我不确定它可能是什么代码,或者甚至可以在C#中进行。
答案 0 :(得分:9)
是的,你可以通过反思来做到这一点:
var fieldInfo = machinePool.GetType().GetField(attribute.Name);
fieldInfo.SetValue(machinePool, attribute.Value);
您还可以创建一个扩展方法,以简化操作:
public static void SetField(this object o, string fieldName, object value)
{
var fi = o.GetType().GetField(fieldName);
fi.SetValue(o, value);
}
答案 1 :(得分:0)
是的,你可以。这里是我想要将属性名称作为字符串(即处理PropertyChangedEventHandler)时使用的一些代码,但我不想自己使用字符串:
public static string GetPropertyName<T>(Expression<Func<T, object>> propertyExpression)
{
Check.RequireNotNull<object>(propertyExpression, "propertyExpression");
switch (propertyExpression.Body.NodeType)
{
case ExpressionType.MemberAccess:
return (propertyExpression.Body as MemberExpression).Member.Name;
case ExpressionType.Convert:
return ((propertyExpression.Body as UnaryExpression).Operand as MemberExpression).Member.Name;
}
var msg = string.Format("Expression NodeType: '{0}' does not refer to a property and is therefore not supported",
propertyExpression.Body.NodeType);
Check.Require(false, msg);
throw new InvalidOperationException(msg);
}
这里有一些测试代码可以帮助您完成它:
[TestFixture]
public class ExpressionsExTests
{
class NumbNut
{
public const string Name = "blah";
public static bool Surname { get { return false; } }
public string Lame;
public readonly List<object> SerendipityCollection = new List<object>();
public static int Age { get { return 12; }}
public static bool IsMammel { get { return _isMammal; } }
private const bool _isMammal = true;
internal static string BiteMe() { return "bitten"; }
}
[Test]
public void NodeTypeIs_Convert_aka_UnaryExpression_Ok()
{
Assert.That(ExpressionsEx.GetPropertyName<NumbNut>(nn => NumbNut.Age), Is.EqualTo("Age"));
Assert.That(ExpressionsEx.GetPropertyName<NumbNut>(nn => NumbNut.IsMammel), Is.EqualTo("IsMammel"));
Assert.That(ExpressionsEx.GetPropertyName<NumbNut>(nn => NumbNut.Surname), Is.EqualTo("Surname"));
}
[Test]
public void NodeTypeIs_MemberAccess_aka_MemberExpression_Ok()
{
Assert.That(ExpressionsEx.GetPropertyName<NumbNut>(nn => nn.SerendipityCollection), Is.EqualTo("SerendipityCollection"));
Assert.That(ExpressionsEx.GetPropertyName<NumbNut>(nn => nn.Lame), Is.EqualTo("Lame"));
}
[Test]
public void NodeTypeIs_Call_Error()
{
CommonAssertions.PreconditionCheck(() => ExpressionsEx.GetPropertyName<NumbNut>(nn => NumbNut.BiteMe()),
"does not refer to a property and is therefore not supported");
}
[Test]
public void NodeTypeIs_Constant_Error() {
CommonAssertions.PreconditionCheck(() => ExpressionsEx.GetPropertyName<NumbNut>(nn => NumbNut.Name),
"does not refer to a property and is therefore not supported");
}
[Test]
public void IfExpressionIsNull_Error()
{
CommonAssertions.NotNullRequired(() => ExpressionsEx.GetPropertyName<NumbNut>(null));
}
[Test]
public void WasPropertyChanged_IfPassedNameIsSameAsNameOfPassedExpressionMember_True()
{
Assert.That(ExpressionsEx.WasPropertyChanged<NumbNut>("SerendipityCollection", nn => nn.SerendipityCollection), Is.True);
}
[Test]
public void WasPropertyChanged_IfPassedPropertyChangeArgNameIsSameAsNameOfPassedExpressionMember_True()
{
var args = new PropertyChangedEventArgs("SerendipityCollection");
Assert.That(ExpressionsEx.WasPropertyChanged<NumbNut>(args, nn => nn.SerendipityCollection), Is.True);
}
}
HTH
Berryl
答案 2 :(得分:0)
您可以执行以下操作:
void SetPropertyToValue(string propertyName, object value)
{
Type type = this.GetType();
type.GetProperty(propertyName).SetValue(this, value, null);
}
然后使用它:
machinePool.SetPropertyToValue(attribute.Name, attribute.Value);