在自己的类中动态设置属性
本文关键字:设置 属性 动态 自己的 | 更新日期: 2023-09-27 18:01:59
我想我已经很接近弄清楚这个问题了,但是我已经有一段时间没有取得进展了,我真的别无选择,只能四处询问。
我有一个具有大量图形属性的GraphicsSettings
类。这些属性有一个带有属性名称的占位符值,我将其用于比较循环。
比较循环是类内部的一个函数,位于图形属性数组和外部文本文件中的Stringreader
之间。
当循环发现图形属性的值与一行中的部分内容相匹配时,我想将该行的整个值设置为图形属性。
这里的问题,虽然,我不知道如何调用属性setter从类中没有特别键入它的名字,我不能这样做,因为它是一个循环。
我试过使用:
this.GetType().GetProperty(key).SetValue(this,line, null);
其中"key"是属性名,"line"是行值。据我所知,当从外部调用类对象来设置值时,这应该工作得很好,但似乎完全反对使用此方法从内部调用类。
我得到的是aTargetInvocationException was unhandled
错误。不太奇怪,但我不知道如何绕过这个。
所以我猜它归结为:我如何通过使用字符串访问属性,从属性所在的同一类内部?
如果属性不是公共的,您可能需要使用绑定标志,因为GetProperty
方法不知道您是从目标类中调用它的。c#的易访问性规则适用于静态代码文本,而不适用于这里。
PropertyInfo prop = this.GetType().GetProperty(key, BindingFlags.Instance |
BindingFlags.NonPublic);
prop.SetValue(this, "data", null);
注意,查找属性是区分大小写的。因此,您可能还需要包含IgnoreCase
标志。
PropertyInfo prop = this.GetType().GetProperty(key, BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.IgnoreCase);
prop.SetValue(this, "data", null);
如果你的属性是静态的,你应该指定BindingFlags.Static
标志而不是BindingFlags.Instance
标志。您还可以将两者结合使用,以及在混合情况下使用BindingFlags.NonPublic | BindingFlags.Public
。
还要注意类型必须匹配。c#的隐式类型转换在这里不起作用。因此,始终为SetValue
的值参数(第二个参数)提供正确的类型。例如
string input = "123";
prop.SetValue(this, Int32.Parse(input), null);
int i = 77;
prop.SetValue(this, (double)i, null);
如果属性类型为double
,也将int
显式转换为double
。
Chris Kerekes建议将prop.MemberType
与Convert.ChangeType
结合使用,以获得一个完全动态的方法,如果您有不同类型的属性(至少对于最常见的类型),该方法将有效。
prop.SetValue(this, Convert.ChangeType(line, prop.MemberType), null);