代码之家  ›  专栏  ›  技术社区  ›  ng.

在C中动态重写抽象方法#

c#
  •  2
  • ng.  · 技术社区  · 14 年前

    我有以下抽象类,不能更改。

    public abstract class AbstractThing {
       public String GetDescription() {
          return "This is " + GetName();
       }
       public abstract String GetName();
    }
    

    现在,我想这样实现一些新的动态类型。

    AssemblyName assemblyName = new AssemblyName();
    assemblyName.Name = "My.TempAssembly";
    AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
    ModuleBuilder moduleBuilder =  assemblyBuilder.DefineDynamicModule("DynamicThings");
    TypeBuilder typeBuilder = moduleBuilder.DefineType(someName + "_Thing", 
                    TypeAttributes.Public | 
                    TypeAttributes.Class, 
                     typeof(AbstractThing));
    MethodBuilder methodBuilder = typeBuilder.DefineMethod("GetName",    
                    MethodAttributes.Public | 
                    MethodAttributes.ReuseSlot |
                    MethodAttributes.Virtual | 
                    MethodAttributes.HideBySig,
                    null,
                    Type.EmptyTypes);
    
    ILGenerator msil = methodBuilder.GetILGenerator();
    
    msil.EmitWriteLine(selectionList);
    msil.Emit(OpCodes.Ret);
    

    但是当我试图通过

    typeBuilder.CreateType();
    

    我得到一个异常,说getname没有实现。我在这里做错什么了吗?我看不出问题所在。

    另外,对于按名称实例化此类类的限制是什么?例如,如果我试图通过“my.tempassembly.x-thing”实例化,它是否可以在不生成类型的情况下用于实例化?

    2 回复  |  直到 14 年前
        1
  •  8
  •   Pent Ploompuu    14 年前

    动态创建的函数的返回类型错误。应该是 string 而不是 void :

    typeBuilder.DefineMethod("GetName",   
    MethodAttributes.Public | 
    MethodAttributes.ReuseSlot |
    MethodAttributes.Virtual | 
    MethodAttributes.HideBySig,
    typeof(string),
    Type.EmptyTypes);
    
        2
  •  3
  •   Dykam    14 年前

    我会用func代替。动态更改方法不需要反射。

    public class AbstractThing {
       public String GetDescription() {
          return "This is " + GetName();
       }
       public Func<String> GetName { get; set; }
    }
    
    var thing = new AbstractThing();
    thing.GetName = () => "Some Name"; // Or any other method
    thing.GetDescription() == "This is Some Name";