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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14724822/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 12:49:35  来源:igfitidea点击:

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

c#.netreflection.net-4.0properties

提问by Royi Namir

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 questionbut it uses interface

我已经阅读了这个问题,但它使用了界面

Thanks in advance.

提前致谢。

采纳答案by dtb

You cannot extend an existing class with new members at runtime. However, you can create a new class using System.Reflection.Emitthat 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[])

回答by Daniel Hilgarth

Yes, you can use the ExpandoObjectclass to achieve this.

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

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

回答by Aron

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. I suggest looking at PostSharpor Fodyif this is what you are interested in.

或者,如果您想在编译时间之后但在运行时间之前以编程方式向类添加属性,您可以查看 IL Weaving/AOP。如果您对此感兴趣,我建议您查看PostSharpFody