C# 使用IL Emit生成一个返回现有对象的虚拟函数

C# 使用IL Emit生成一个返回现有对象的虚拟函数,c#,cil,C#,Cil,我想在我的C#code中动态生成BasicModel的派生类。我想重写派生类中的虚拟属性以返回一个已存在的对象 public class BasicModel { [IgnoreProperty] public virtual CloudStorageAccount StorageAccount { get; } } 这里是IL部分。但是我经常从调用该方法中得到null var IlGen2 = newMethod2.GetILGenerator(); Func<Clou

我想在我的C#code中动态生成
BasicModel
的派生类。我想重写派生类中的虚拟属性以返回一个已存在的对象

public class BasicModel
{
    [IgnoreProperty]
    public virtual CloudStorageAccount StorageAccount { get; }
}
这里是IL部分。但是我经常从调用该方法中得到
null

var IlGen2 = newMethod2.GetILGenerator();
Func<CloudStorageAccount> getStoredObj = () => parentModel.StorageAccount;
IlGen2.Emit(OpCodes.Call, getStoredObj.GetMethodInfo());
IlGen2.Emit(OpCodes.Ldobj);
IlGen2.Emit(OpCodes.Ret);
var IlGen2=newMethod2.GetILGenerator();
Func getStoredObj=()=>parentModel.StorageAccount;
Emit(opcode.Call,getStoredObj.GetMethodInfo());
IlGen2.Emit(操作码Ldobj);
IlGen2.Emit(操作码.Ret);
有什么问题吗?还是有更好的办法


非常感谢。

由于委托对于该类型的所有实例都是相同的,因此我将定义一个包含委托的静态字段,并使用该字段:

static void Main(string[] args)
{

    var parentModel = new ContainerCloudStorageAccount { StorageAccount = new CloudStorageAccount() } ;
    var type = CreateType("MyOverride", () => parentModel.StorageAccount);
    var value = (BasicModel)type.GetConstructors().First().Invoke(new object[0]);
    Console.WriteLine(value.StorageAccount);
}

public static Type CreateType(string name, Func<CloudStorageAccount> getter)
{ 
    AppDomain myDomain = Thread.GetDomain();
    AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(new AssemblyName("dynamicTypes"), AssemblyBuilderAccess.Run);
    ModuleBuilder interfaceImplementationModule = myAsmBuilder.DefineDynamicModule("overrrides");

    TypeBuilder typeBuilder = interfaceImplementationModule.DefineType(name,
        TypeAttributes.Public | TypeAttributes.Class,
        typeof(BasicModel));

    var newMethod2 = typeBuilder.DefineMethod("get_StorageAccount", MethodAttributes.Virtual | MethodAttributes.Public,
            typeof(CloudStorageAccount), Type.EmptyTypes
    );
    typeBuilder.DefineMethodOverride(newMethod2, typeof(BasicModel).GetProperty("StorageAccount").GetGetMethod());

    var fieldInfo = typeBuilder.DefineField("getter", typeof(Func<CloudStorageAccount>), FieldAttributes.Static | FieldAttributes.Public);

    var IlGen2 = newMethod2.GetILGenerator();
    IlGen2.Emit(OpCodes.Ldsfld, fieldInfo);
    IlGen2.Emit(OpCodes.Call, typeof(Func<CloudStorageAccount>).GetMethod("Invoke"));
    IlGen2.Emit(OpCodes.Ret);

    typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);
    var type = typeBuilder.CreateType();
    type.GetField("getter").SetValue(null, getter);

    return type;
}
static void Main(字符串[]args)
{
var parentModel=newcontainercloudstorageaccount{StorageAccount=newcloudstorageaccount()};
var type=CreateType(“MyOverride”,()=>parentModel.StorageAccount);
var value=(BasicModel)type.GetConstructors().First().Invoke(新对象[0]);
Console.WriteLine(value.StorageAccount);
}
公共静态类型CreateType(字符串名,Func getter)
{ 
AppDomain myDomain=Thread.GetDomain();
AssemblyBuilder myAsmBuilder=myDomain.DefinedDynamicAssembly(新的AssemblyName(“dynamicTypes”),AssemblyBuilderAccess.Run);
ModuleBuilder接口实现模块=myAsmBuilder.DefinedDynamicModule(“Overrides”);
TypeBuilder TypeBuilder=interfaceImplementationModule.DefineType(名称,
TypeAttributes.Public | TypeAttributes.Class,
类型(基本模型);
var newMethod2=typeBuilder.DefineMethod(“get_StorageAccount”,MethodAttributes.Virtual,MethodAttributes.Public,
typeof(CloudStorageAccount),Type.EmptyTypes
);
typeBuilder.definemethodverride(newMethod2,typeof(BasicModel).GetProperty(“StorageAccount”).GetGetMethod());
var fieldInfo=typeBuilder.DefineField(“getter”,typeof(Func),FieldAttributes.Static | FieldAttributes.Public);
var IlGen2=newMethod2.GetILGenerator();
IlGen2.Emit(opcode.Ldsfld,fieldInfo);
Emit(OpCodes.Call,typeof(Func.GetMethod(“Invoke”));
IlGen2.Emit(操作码.Ret);
typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);
var type=typeBuilder.CreateType();
type.GetField(“getter”).SetValue(null,getter);
返回类型;
}

原始解决方案不起作用,因为委托不仅仅是一个方法,它也是该方法的目标对象。因此,如果您只调用与委托关联的方法,它将不包含您在委托中捕获的数据

要与类关联的委托对于所有实例都是相同的?也就是说,对于动态类型的所有实例,parentModel.StorageAccount都将是相同的?@TitianCernicova Dragomir thx供您回复。对于不同的类型,
parentModel
是不同的。