在自己的类中动态设置属性

时间:2013-03-04 12:30:58

标签: c# class dynamic properties

我认为我已经非常接近这一点,但我现在已经有一段时间没有取得进展了,除了四处询问之外别无选择。

我有一个GraphicsSettings类,其中包含大量图形属性。这些属性的占位符值带有属性的名称,我将其用于比较循环。

比较循环是类中的一个函数,位于图形属性数组和外部文本文件中的Stringreader行之间。

当循环找到图形属性的值与行内部分的匹配时,我想将行的整个值设置为图形属性。

在这里遇到了问题,我不知道怎么从类中调用属性setter而没有特别输入它的名字,这是我从循环开始就做不到的。

我尝试过使用:

this.GetType().GetProperty(key).SetValue(this,line, null);

" key"是属性名称和" line"是线值。根据我的理解,当从外部调用类对象来设置值时,这应该可以正常工作,但它似乎完全反对使用此方法从内部调用类。

我得到的只是一个  TargetInvocationException was unhandled错误。不太令人惊讶,但我不知道如何解决这个问题。

所以我想它归结为:我如何通过使用字符串从属性所在的同一个类中访问属性?

1 个答案:

答案 0 :(得分:4)

如果属性不是公共的,则可能需要使用绑定标志,因为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.PublicSetValue结合使用。


另请注意,类型必须匹配。 C#的隐式类型转换在这里不起作用。因此,始终为string input = "123"; prop.SetValue(this, Int32.Parse(input), null); int i = 77; prop.SetValue(this, (double)i, null); 的值参数(第二个参数)提供正确的类型。 E.g。

int

如果属性类型为double,也会明确地将double转换为prop.MemberType


Chris Kerekes建议将Convert.ChangeTypeprop.SetValue(this, Convert.ChangeType(line, prop.MemberType), null); 结合使用,以获得一个完全动态的方法,如果您拥有不同类型的属性(至少对于最常见的类型),它将起作用。

{{1}}