如何在C#中在运行时添加类属性?

17

我有一个类:

class MyClass 
{
}
...
MyClass c = new MyClass();

是否可以在运行时向此类添加属性/字段?

我不知道它们在编译时的类型或名称,它们也没有一个我可以使用的公共接口。

伪代码示例:

 Add property named "Prop1" [type System.Int32]
 Add property named "Prop900" [type System.String]

我已经阅读了这篇问题,但它使用了接口

提前致谢。


3
然后通过反射随处访问它们?Dictionary<string, object> 怎么样? - H H
@HenkHolterman 是的,Henk。稍后我将使用 MyClass.GetType().GetProperties() 访问它们。 - Royi Namir
1
你需要它用于什么用例?ICustomTypeDescriptor呢? - Dennis
1
@RoyiNamir:反射不是关于 IL 修改 - 那是你想要实现的目标。 - Dennis
1
为什么你想通过直接跳入其中可能是最糟糕的用法,来“学习”反射呢? - Jason Larke
3个回答

49

4
我已经成功完成了它,谢谢(那就是方法)。感谢您回答实际问题。 - Royi Namir
好的回答。不过链接已经失效了,更新它们会帮助未来的其他人。 :-) - Delphi.Boy

6
我认为你误解了反射的含义。反射不允许您更改正在运行的代码。它可以让您读取自己的代码,甚至运行该代码。
使用Reflection.Emit,您可以编写一个全新的程序集,然后将其加载到内存中。
但是您无法在运行时更改类。想象一下,您有一个名为Foo的类,您实例化了许多这样的类,然后决定更改该类。
那么您已经实例化的所有Foos应该怎么办?
但是,您可以使用Reflection.Emit创建一个继承自Foo的新类,称为Bar,然后向该类添加所需内容。
或者,如果您想在编译时间之后但在运行时间之前以编程方式向类添加属性,则可以查看IL Weaving / AOP。如果您对此感兴趣,建议查看PostSharpFody

2

是的,您可以使用ExpandoObject类来实现这一点。

dynamic expando = new ExpandoObject();
expando.Prop1 = 10;
expando.Prop900 = string.Empty;

1
它在内部使用字典实现。我需要一个纯粹的类,带有属性。 - Royi Namir
1
GetType().GetProperties() 可能比使用 Dictionary 效率低。 - H H
我们是否可以使用ExpandoObject指定这些属性的数据类型呢? - Iqra.
你的场景是什么? - Daniel Hilgarth
实际上,Prop1到Prop900不是属性,而是字典项,因为expanto.GetType().GetProperties()不返回这些属性。 - Ramil Aliyev 007

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接