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

C# 在自己的类中动态设置属性,c#,class,dynamic,properties,C#,Class,Dynamic,Properties,我想我很快就能解决这个问题了,但我已经有一段时间没有进步了,除了四处打听,我真的没有选择 我有一个GraphicsSettings类,其中包含大量的图形属性。这些属性有一个带有属性名称的占位符值,我将其用于比较循环 比较循环是类中的一个函数,位于图形属性数组和外部文本文件中的行上的Stringreader之间 当循环在图形属性的值和一行中的部分内容之间找到匹配项时,我希望将该行的整个值设置为graphics属性 但问题是,我不知道如何从类中调用属性setter,而不明确地键入它的名称,因为它是一

我想我很快就能解决这个问题了,但我已经有一段时间没有进步了,除了四处打听,我真的没有选择

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

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

当循环在图形属性的值和一行中的部分内容之间找到匹配项时,我希望将该行的整个值设置为graphics属性

但问题是,我不知道如何从类中调用属性setter,而不明确地键入它的名称,因为它是一个循环,所以我无法这样做

我试过使用:

this.GetType().GetProperty(key).SetValue(this,line, null);
其中key是属性名,line是行值。据我所知,当从外部调用类对象来设置值时,这应该可以很好地工作,但似乎完全不允许使用此方法从内部调用类

我得到的只是一个 TargetInvocationException是未处理的错误。这并不奇怪,但我不知道该怎么解决这个问题


因此,我想归结到这一点:如何通过使用字符串从属性所在的同一类内部访问属性?

如果属性不是公共的,您可能需要使用绑定标志,因为GetProperty方法不知道您是从目标类内部调用它。C的可访问性规则适用于静态代码文本,不适用于此处

PropertyInfo prop = this.GetType().GetProperty(key, BindingFlags.Instance | 
                                                    BindingFlags.NonPublic);
prop.SetValue(this, "data", null);
请注意,查找属性区分大小写。因此,您可能还需要包含IgnoreCase标志

如果属性是静态的,则应指定BindingFlags.static标志,而不是BindingFlags.Instance标志。对于混合情况,您还可以同时使用BindingFlags.NonPublic | BindingFlags.Public和BindingFlags

还要注意,类型必须匹配。C的隐式类型转换在这里不起作用。因此,请始终为SetValue的值参数第二个参数提供正确的类型。例如

如果属性的类型为double,还可以显式地将int转换为double

Chris Kerekes建议将prop.MemberType与Convert.ChangeType结合使用,以获得一种完全动态的方法,如果您的属性至少对于最常见的类型具有不同的类型,则该方法将有效

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

如果属性不是公共的,您可能需要使用绑定标志,因为GetProperty方法不知道您是从目标类中调用它的。C的可访问性规则适用于静态代码文本,不适用于此处

PropertyInfo prop = this.GetType().GetProperty(key, BindingFlags.Instance | 
                                                    BindingFlags.NonPublic);
prop.SetValue(this, "data", null);
请注意,查找属性区分大小写。因此,您可能还需要包含IgnoreCase标志

如果属性是静态的,则应指定BindingFlags.static标志,而不是BindingFlags.Instance标志。对于混合情况,您还可以同时使用BindingFlags.NonPublic | BindingFlags.Public和BindingFlags

还要注意,类型必须匹配。C的隐式类型转换在这里不起作用。因此,请始终为SetValue的值参数第二个参数提供正确的类型。例如

如果属性的类型为double,还可以显式地将int转换为double

Chris Kerekes建议将prop.MemberType与Convert.ChangeType结合使用,以获得一种完全动态的方法,如果您的属性至少对于最常见的类型具有不同的类型,则该方法将有效

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

我认为您需要发布一些代码,包括引发异常的行,因为这应该没有问题。此外,TargetInvocationException可能非常具有欺骗性。请务必检查所有嵌套的InnerException,因为它们很可能会让您更好地了解真实情况,根本原因。假设key实际上是区分大小写的属性名,并且该行没有打破任何类型边界,例如将null设置为int,则没有直接原因表明该行会失败。我认为您需要发布一些代码,包括引发异常的行,因为这应该没有问题。另外,一个特例可能非常具有欺骗性。请务必检查所有嵌套的InnerException,因为它们很可能会让您更好地了解真实情况,根本原因。假设键实际上是区分大小写的属性名称,并且该行没有打破任何类型边界,例如将null设置为int,则没有直接原因导致该行失败。答案很好,尽管我可能建议通过prop.SetValuethis、Convert.ChangeTypeline、prop.MemberType、null转换clr类型;工作就像一种魅力;非常感谢。@Chris Kerekes:是的,您的解决方案允许一种非常动态的方法。答案很好,尽管我可能会建议通过prop.SetValuethis,Convert.Chang转换clr类型
eTypeline,prop.MemberType,null;工作就像一种魅力;非常感谢。@Chris Kerekes:是的,您的解决方案允许非常动态的方法。