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

本文关键字:设置 属性 动态 自己的 | 更新日期: 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.MemberTypeConvert.ChangeType结合使用,以获得一个完全动态的方法,如果您有不同类型的属性(至少对于最常见的类型),该方法将有效。

prop.SetValue(this, Convert.ChangeType(line, prop.MemberType), null);