简体   繁体   English

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

[英]How Can I add properties to a class on runtime in C#?

I have a class : 我有一节课:

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

Is it possible to add properties / fields to this class on run-time ? 是否可以在运行时向此类添加属性/字段?

( I don't know what are their types or names on compile-time and they don't have a common interface which I can use. ) 我不知道它们在编译时的类型或名称是什么,它们没有我可以使用的通用接口。

psuedo example : 假的例子:

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

I already read this question but it uses interface 我已经阅读了这个问题,但它使用了界面

Thanks in advance. 提前致谢。

You cannot extend an existing class with new members at runtime. 您无法在运行时使用新成员扩展现有类。 However, you can create a new class using System.Reflection.Emit that has the existing class as base class. 但是,您可以使用System.Reflection.Emit创建一个新类,该类具有现有类作为基类。

typeBuilder.SetParent(typeof(MyClass));
typeBuilder.DefineProperty("Prop1", ..., typeof(System.Int32), null);
...

See TypeBuilder.DefineProperty Method (String, PropertyAttributes, Type, Type[]) for a full example. 有关完整示例请参见TypeBuilder.DefineProperty方法(String,PropertyAttributes,Type,Type [])

I think you have misunderstood what reflection is. 我想你误解了反思是什么。 Reflection does not allow you to change the code you are running. 反射不允许您更改正在运行的代码。 It can allow you to read your own code and even run that code. 它可以让您阅读自己的代码,甚至运行该代码。

With Reflection.Emit you can write a whole new assembly and then have it loaded into memory. 使用Reflection.Emit,您可以编写一个全新的程序集,然后将其加载到内存中。

However you CANNOT change a class at runtime. 但是,您无法在运行时更改类。 Imagine, you have a class Foo, you instanciate a whole bunch of them, then decide to change the class. 想象一下,你有一个Foo类,你实现了一大堆,然后决定改变这个类。

What should happen to all the Foos you already instanciated? 你已经实施的所有Foos应该怎么办?

However, what you CAN do it use Reflection.Emit to create a new class that inherits Foo, called Bar, and then add whatever you need to that class. 但是,您可以使用Reflection.Emit创建一个继承Foo的新类,称为Bar,然后向该类添加所需的任何内容。

Alternatively if you want to programmatically add a property to a class AFTER compile time but BEFORE run time, you can look at IL Weaving/AOP. 或者,如果要在编译时间之后以编程方式将属性添加到类,但在运行时之前,可以查看IL Weaving / AOP。 I suggest looking at PostSharp or Fody if this is what you are interested in. 如果这是您感兴趣的话,我建议您查看PostSharpFody

Yes, you can use the ExpandoObject class to achieve this. 是的,您可以使用ExpandoObject类来实现此目的。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM