zan*_*ona 43 c# string eval accessor databinder
我有一个Account班级的实例.每个帐户对象都有一个所有者,参考等.
我可以访问帐户属性的一种方法是通过访问器
account.Reference;
Run Code Online (Sandbox Code Playgroud)
但我希望能够使用动态字符串选择器访问它,如:
account["PropertyName"];
Run Code Online (Sandbox Code Playgroud)
就像在JavaScript中一样.所以我会有account["Reference"]哪些会返回值,但我也希望能够在之后分配一个新值,如:
account["Reference"] = "124ds4EE2s";
Run Code Online (Sandbox Code Playgroud)
我注意到我可以使用
DataBinder.Eval(account,"Reference")
Run Code Online (Sandbox Code Playgroud)
获取基于字符串的属性,但使用此属性我无法为属性赋值.
我怎么能这样做?
Ada*_*son 68
首先,你应该避免使用它; C#是一种强类型语言,因此请充分利用该方面的类型安全性和性能优势.
如果你有合理的理由动态获取和设置属性的值(换句话说,当代码中无法定义类型和/或属性名称时),那么你将不得不使用反射.
最直观的方式是:
object value = typeof(YourType).GetProperty("PropertyName").GetValue(yourInstance);
...
typeof(YourType).GetProperty("PropertyName").SetValue(yourInstance, "value");
Run Code Online (Sandbox Code Playgroud)
但是,您可以缓存PropertyInfo对象以使其更具可读性:
System.Reflection.PropertyInfo prop = typeof(YourType).GetProperty("PropertyName");
object value = prop.GetValue(yourInstance);
...
prop.SetValue(yourInstance, "value");
Run Code Online (Sandbox Code Playgroud)
Ric*_*end 32
您可以尝试将索引器与反射结合起来......
public object this[string propertyName]
{
get
{
PropertyInfo property = GetType().GetProperty(propertyName);
return property.GetValue(this, null);
}
set
{
PropertyInfo property = GetType().GetProperty(propertyName);
property.SetValue(this,value, null);
}
}
Run Code Online (Sandbox Code Playgroud)
如果它们是您自己的对象,您可以提供索引器来访问字段.我不是真的推荐这个,但它会允许你想要的东西.
public object this[string propertyName]
{
get
{
if(propertyName == "Reference")
return this.Reference;
else
return null;
}
set
{
if(propertyName == "Reference")
this.Reference = value;
else
// do error case here
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,执行此操作时会丢失类型安全性.
如果您使用的是.Net 4,则可以立即使用dynamic关键字。
dynamic foo = account;
foo.Reference = "124ds4EE2s";
Run Code Online (Sandbox Code Playgroud)
我使用了Richard的反射方法,但是详细说明了set方法来处理正在使用的其他类型,例如字符串和空值.
public object this[string propertyName]
{
get
{
PropertyInfo property = GetType().GetProperty(propertyName);
return property.GetValue(this, null);
}
set
{
PropertyInfo property = GetType().GetProperty(propertyName);
Type propType = property.PropertyType;
if (value == null)
{
if (propType.IsValueType && Nullable.GetUnderlyingType(propType) == null)
{
throw new InvalidCastException();
}
else
{
property.SetValue(this, null, null);
}
}
else if (value.GetType() == propType)
{
property.SetValue(this, value, null);
}
else
{
TypeConverter typeConverter = TypeDescriptor.GetConverter(propType);
object propValue = typeConverter.ConvertFromString(value.ToString());
property.SetValue(this, propValue, null);
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果转换不起作用,SetValue()函数将抛出错误.