c#中可以给一个类动态增加成员吗?

时间:2022-08-30 19:51:52
请问:c#中可以给一个类动态增加成员吗?
好象System.Runtime.InteropServices.Expando.IExpando中有此类方法,但如何实现呢?请赐教,谢谢!最好不要遍历程序集。

26 个解决方案

#1


哎。无人问津,自己UP一下。。。

#2


请高人指点一二...

#3


我只知道可以遍历成员, 不知道能否增加~~
你可以放一个ArrayList成员,对ArrayList进行增删`

#4


可以可以!C#支持动态生成代码动态编译,这可不是太简单,三两句说不完。
你要这样实现什么呢???

#5


System.CodeDom 命名空间包含可以用于表示源代码文档的元素和结构的类。此命名空间中的类可用来建立源代码文档结构的模型,使用 System.CodeDom.Compiler 命名空间提供的功能可以将源代码文档输出为所支持语言的源代码。

这两个名字空间下的类可以作动态编译.如果你想在已经编译了的类里增加东东, 估计不行.

#6


是的,动态编译我知道。

我是想在已经编译了的类里增加东东。。。



#7


你在自己的类里声明一个object成员,你想放什么进去都行,甚至整个宇宙。。。

#8


这样说好了:


这个问题源自面向对象(OO)开发中的一个思考。

对象A拥有若干[属性](attr1,attr2,...),注意这里的属性可能是个有意义的对象;
现在要求在运行时,动态添加A的成员。

后来在项目实现时我还是采用了动态存储,动态加载这样的机制使得看起来像OO;

请恕在下才疏学浅,对OO的理解真的不够深入;
想借机听听各位大侠的意见~~~~

谢谢以上各位大侠的支持^_^

#9


关注一下

#10


没听说过

#11


用CodeDOM 生成一段DOM程序,如果这段DOM是方法,不能直接调用,要将其“发射”(Emit)到一个类(实例?不记得了)中,再从该类调用这个方法。我想这就是你想要的吧,具体见MSDN中CodeDOM部分

#12


你可以用codedom来生成一个.cs文件。
但是如果是要在运行时来给已经编译过的类添加一个成员的话,恕我孤陋寡闻,不行

#13


不能吧,编译的时候都定好了的

#14


C#的类编译以后就封装了,好象不能实现动态增加方法.

#15


有可能吗?

#16


不知道你了不了解设计模式,
你可以去看一下Decorator Pattern
 
需要动态地给一个对象增加功能,这些功能可以再动态地撤销,这就是它的一个作用. 

#17


应该比较困难吧?
不过看起来好像有点OO的味道,比如说一个人,他的能力或者行为是会随着时间增加或者改变的,但至于在语言上怎样实现我的确没有听说过。
不知道有没有什么好的替代方案?应该和设计模式有关吧。

#18


这已经超越了面向对象,这是一种面向原型的编程语言,self、javascript这两种语言就是这样的语言。.NET好像不是基于这种模型的,所以不行。

#19


Of course
First, you must get the type of your class. Now I give you a sample. 
There is a Form1, if you want to add a dynamic method in the Form1 when the assembly is running. You may use Reflection Emit API to do that.

The method we will add is :
public String Method(String str)
{
    return "Hello:" + str;
}

The method will be added to the Form1 when the assembly containing the Form1 is running. Then it will be run.

step0: you must use one namespace: using System.Reflection.Emit; 

step1: declare a delegate

public delegate String MyMethod(String str);

step2: create a dynamic method

  Type[] argsType = { typeof(String) };  // argument type of the MyMethod1
  DynamicMethod dm = new DynamicMethod("MyMethod1", typeof(String), argsType,  typeof(Form1).Module);

step3: writing the code of the MyMethod1( note: IL(Intermedial language must be used)

ILGenerator il = dm.GetILGenerator();  // get the IL generator of the MyMethod1

il.Emit(OpCodes.Ldstr, "hello:");  // push the "hello:" string onto the evaluation stack
il.Emit(OpCodes.Ldarg_0);          // push the first argument of the MyMethod1 onto the evaluation stack
// call the Concat method of the String class (it is static)
il.Emit(OpCodes.Call, typeof(String).GetMethod( "Concat", new Type[]{typeof(String), typeof(String)}));
il.Emit(OpCodes.Ret);  // return the "Hello:" + str;

step4: show the return value
MyMethod my = (MyMethod)dm.CreateDelegate(typeof(MyMethod));
MessageBox.Show(my("my friends"));

Ok, you succeed!

An alternative is Codedom. You can use source code here. The information about codedom will be find on msdn(online or offline).

good luck.

#20


f course
First, you must get the type of your class. Now I give you a sample. 
There is a Form1, if you want to add a dynamic method in the Form1 when the assembly is running. You may use Reflection Emit API to do that.

The method we will add is :
public String Method(String str)
{
    return "Hello:" + str;
}

The method will be added to the Form1 when the assembly containing the Form1 is running. Then it will be run.

step0: you must use one namespace: using System.Reflection.Emit; 

step1: declare a delegate

public delegate String MyMethod(String str);

step2: create a dynamic method

  Type[] argsType = { typeof(String) };  // argument type of the MyMethod1
  DynamicMethod dm = new DynamicMethod("MyMethod1", typeof(String), argsType,  typeof(Form1).Module);

step3: writing the code of the MyMethod1( note: IL(Intermedial language) must be used)

ILGenerator il = dm.GetILGenerator();  // get the IL generator of the MyMethod1

il.Emit(OpCodes.Ldstr, "hello:");  // push the "hello:" string onto the evaluation stack
il.Emit(OpCodes.Ldarg_0);          // push the first argument of the MyMethod1 onto the evaluation stack
// call the Concat method of the String class (it is static)
il.Emit(OpCodes.Call, typeof(String).GetMethod( "Concat", new Type[]{typeof(String), typeof(String)}));
il.Emit(OpCodes.Ret);  // return the "Hello:" + str;

step4: show the return value
MyMethod my = (MyMethod)dm.CreateDelegate(typeof(MyMethod));
MessageBox.Show(my("my friends"));

Ok, you succeed!

An alternative is Codedom. You can use source code here. The information about codedom will be found on msdn(online or offline).

#21


Of course
First, you must get the type of your class. Now I give you a sample. 
There is a Form1, if you want to add a dynamic method in the Form1 when the assembly is running. You may use Reflection Emit API to do that.

The method we will add is :
public String Method(String str)
{
    return "Hello:" + str;
}

The method will be added to the Form1 when the assembly containing the Form1 is running. Then it will be run.

step0: you must use one namespace: using System.Reflection.Emit; 

step1: declare a delegate

public delegate String MyMethod(String str);

step2: create a dynamic method

  Type[] argsType = { typeof(String) };  // argument type of the MyMethod1
  DynamicMethod dm = new DynamicMethod("MyMethod1", typeof(String), argsType,  typeof(Form1).Module);

step3: writing the code of the MyMethod1( note: IL(Intermedial language) must be used)

ILGenerator il = dm.GetILGenerator();  // get the IL generator of the MyMethod1

il.Emit(OpCodes.Ldstr, "hello:");  // push the "hello:" string onto the evaluation stack
il.Emit(OpCodes.Ldarg_0);          // push the first argument of the MyMethod1 onto the evaluation stack
// call the Concat method of the String class (it is static)
il.Emit(OpCodes.Call, typeof(String).GetMethod( "Concat", new Type[]{typeof(String), typeof(String)}));
il.Emit(OpCodes.Ret);  // return the "Hello:" + str;

step4: show the return value
MyMethod my = (MyMethod)dm.CreateDelegate(typeof(MyMethod));
MessageBox.Show(my("my friends"));

Ok, you succeed!

An alternative is Codedom. You can use source code here. The information about codedom will be found on msdn(online or offline).

good luck.

#22


TO  bughole(虫洞)

您的这个例子是动态生成一个方法并绑给一个委托是吗?

虽然我没有试过,但还是蛮值得学习的。

btw:

如何加一个member呢?

#23


TO  lovewindy(LOVE风云)

谢谢,
设计模式读过一点,了解很肤浅;
您可否再解释详细一点?
谢谢!

#24


What's member?  property? or others

#25


Method is also member method. Member contains methods, property, field and so on. You say which it is.

#26


property, field

#1


哎。无人问津,自己UP一下。。。

#2


请高人指点一二...

#3


我只知道可以遍历成员, 不知道能否增加~~
你可以放一个ArrayList成员,对ArrayList进行增删`

#4


可以可以!C#支持动态生成代码动态编译,这可不是太简单,三两句说不完。
你要这样实现什么呢???

#5


System.CodeDom 命名空间包含可以用于表示源代码文档的元素和结构的类。此命名空间中的类可用来建立源代码文档结构的模型,使用 System.CodeDom.Compiler 命名空间提供的功能可以将源代码文档输出为所支持语言的源代码。

这两个名字空间下的类可以作动态编译.如果你想在已经编译了的类里增加东东, 估计不行.

#6


是的,动态编译我知道。

我是想在已经编译了的类里增加东东。。。



#7


你在自己的类里声明一个object成员,你想放什么进去都行,甚至整个宇宙。。。

#8


这样说好了:


这个问题源自面向对象(OO)开发中的一个思考。

对象A拥有若干[属性](attr1,attr2,...),注意这里的属性可能是个有意义的对象;
现在要求在运行时,动态添加A的成员。

后来在项目实现时我还是采用了动态存储,动态加载这样的机制使得看起来像OO;

请恕在下才疏学浅,对OO的理解真的不够深入;
想借机听听各位大侠的意见~~~~

谢谢以上各位大侠的支持^_^

#9


关注一下

#10


没听说过

#11


用CodeDOM 生成一段DOM程序,如果这段DOM是方法,不能直接调用,要将其“发射”(Emit)到一个类(实例?不记得了)中,再从该类调用这个方法。我想这就是你想要的吧,具体见MSDN中CodeDOM部分

#12


你可以用codedom来生成一个.cs文件。
但是如果是要在运行时来给已经编译过的类添加一个成员的话,恕我孤陋寡闻,不行

#13


不能吧,编译的时候都定好了的

#14


C#的类编译以后就封装了,好象不能实现动态增加方法.

#15


有可能吗?

#16


不知道你了不了解设计模式,
你可以去看一下Decorator Pattern
 
需要动态地给一个对象增加功能,这些功能可以再动态地撤销,这就是它的一个作用. 

#17


应该比较困难吧?
不过看起来好像有点OO的味道,比如说一个人,他的能力或者行为是会随着时间增加或者改变的,但至于在语言上怎样实现我的确没有听说过。
不知道有没有什么好的替代方案?应该和设计模式有关吧。

#18


这已经超越了面向对象,这是一种面向原型的编程语言,self、javascript这两种语言就是这样的语言。.NET好像不是基于这种模型的,所以不行。

#19


Of course
First, you must get the type of your class. Now I give you a sample. 
There is a Form1, if you want to add a dynamic method in the Form1 when the assembly is running. You may use Reflection Emit API to do that.

The method we will add is :
public String Method(String str)
{
    return "Hello:" + str;
}

The method will be added to the Form1 when the assembly containing the Form1 is running. Then it will be run.

step0: you must use one namespace: using System.Reflection.Emit; 

step1: declare a delegate

public delegate String MyMethod(String str);

step2: create a dynamic method

  Type[] argsType = { typeof(String) };  // argument type of the MyMethod1
  DynamicMethod dm = new DynamicMethod("MyMethod1", typeof(String), argsType,  typeof(Form1).Module);

step3: writing the code of the MyMethod1( note: IL(Intermedial language must be used)

ILGenerator il = dm.GetILGenerator();  // get the IL generator of the MyMethod1

il.Emit(OpCodes.Ldstr, "hello:");  // push the "hello:" string onto the evaluation stack
il.Emit(OpCodes.Ldarg_0);          // push the first argument of the MyMethod1 onto the evaluation stack
// call the Concat method of the String class (it is static)
il.Emit(OpCodes.Call, typeof(String).GetMethod( "Concat", new Type[]{typeof(String), typeof(String)}));
il.Emit(OpCodes.Ret);  // return the "Hello:" + str;

step4: show the return value
MyMethod my = (MyMethod)dm.CreateDelegate(typeof(MyMethod));
MessageBox.Show(my("my friends"));

Ok, you succeed!

An alternative is Codedom. You can use source code here. The information about codedom will be find on msdn(online or offline).

good luck.

#20


f course
First, you must get the type of your class. Now I give you a sample. 
There is a Form1, if you want to add a dynamic method in the Form1 when the assembly is running. You may use Reflection Emit API to do that.

The method we will add is :
public String Method(String str)
{
    return "Hello:" + str;
}

The method will be added to the Form1 when the assembly containing the Form1 is running. Then it will be run.

step0: you must use one namespace: using System.Reflection.Emit; 

step1: declare a delegate

public delegate String MyMethod(String str);

step2: create a dynamic method

  Type[] argsType = { typeof(String) };  // argument type of the MyMethod1
  DynamicMethod dm = new DynamicMethod("MyMethod1", typeof(String), argsType,  typeof(Form1).Module);

step3: writing the code of the MyMethod1( note: IL(Intermedial language) must be used)

ILGenerator il = dm.GetILGenerator();  // get the IL generator of the MyMethod1

il.Emit(OpCodes.Ldstr, "hello:");  // push the "hello:" string onto the evaluation stack
il.Emit(OpCodes.Ldarg_0);          // push the first argument of the MyMethod1 onto the evaluation stack
// call the Concat method of the String class (it is static)
il.Emit(OpCodes.Call, typeof(String).GetMethod( "Concat", new Type[]{typeof(String), typeof(String)}));
il.Emit(OpCodes.Ret);  // return the "Hello:" + str;

step4: show the return value
MyMethod my = (MyMethod)dm.CreateDelegate(typeof(MyMethod));
MessageBox.Show(my("my friends"));

Ok, you succeed!

An alternative is Codedom. You can use source code here. The information about codedom will be found on msdn(online or offline).

#21


Of course
First, you must get the type of your class. Now I give you a sample. 
There is a Form1, if you want to add a dynamic method in the Form1 when the assembly is running. You may use Reflection Emit API to do that.

The method we will add is :
public String Method(String str)
{
    return "Hello:" + str;
}

The method will be added to the Form1 when the assembly containing the Form1 is running. Then it will be run.

step0: you must use one namespace: using System.Reflection.Emit; 

step1: declare a delegate

public delegate String MyMethod(String str);

step2: create a dynamic method

  Type[] argsType = { typeof(String) };  // argument type of the MyMethod1
  DynamicMethod dm = new DynamicMethod("MyMethod1", typeof(String), argsType,  typeof(Form1).Module);

step3: writing the code of the MyMethod1( note: IL(Intermedial language) must be used)

ILGenerator il = dm.GetILGenerator();  // get the IL generator of the MyMethod1

il.Emit(OpCodes.Ldstr, "hello:");  // push the "hello:" string onto the evaluation stack
il.Emit(OpCodes.Ldarg_0);          // push the first argument of the MyMethod1 onto the evaluation stack
// call the Concat method of the String class (it is static)
il.Emit(OpCodes.Call, typeof(String).GetMethod( "Concat", new Type[]{typeof(String), typeof(String)}));
il.Emit(OpCodes.Ret);  // return the "Hello:" + str;

step4: show the return value
MyMethod my = (MyMethod)dm.CreateDelegate(typeof(MyMethod));
MessageBox.Show(my("my friends"));

Ok, you succeed!

An alternative is Codedom. You can use source code here. The information about codedom will be found on msdn(online or offline).

good luck.

#22


TO  bughole(虫洞)

您的这个例子是动态生成一个方法并绑给一个委托是吗?

虽然我没有试过,但还是蛮值得学习的。

btw:

如何加一个member呢?

#23


TO  lovewindy(LOVE风云)

谢谢,
设计模式读过一点,了解很肤浅;
您可否再解释详细一点?
谢谢!

#24


What's member?  property? or others

#25


Method is also member method. Member contains methods, property, field and so on. You say which it is.

#26


property, field