gpt4 book ai didi

c# - 动态创建类型并调用基类的构造函数

转载 作者:可可西里 更新时间:2023-11-01 08:42:06 28 4
gpt4 key购买 nike

我需要动态创建一个类。大多数事情都运行良好,但我一直在生成构造函数。

AssemblyBuilder _assemblyBuilder =
AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("MyBuilder"), AssemblyBuilderAccess.Run);

ModuleBuilder _moduleBuilder = _assemblyBuilder.DefineDynamicModule("MyModule");

public static object GetInstance<TSource, TEventArgs>(this TSource source, string eventName)
where TSource : class
{
var typeName = "MyTypeName";
var typeBuilder = _moduleBuilder.DefineType(typeName, TypeAttributes.Class | TypeAttributes.Public);

// create type like class MyClass : GenericType<MyClass, TSource, TEventArgs>
var baseNotGenericType = typeof(GenericType<,,>);
var baseType = baseNotGenericType.MakeGenericType(typeBuilder, typeof(TSource), typeof(TEventArgs));
typeBuilder.SetParent(baseType);


// the base class contains one constructor with string as param
var baseCtor = baseNotGenericType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(string) }, null);

var ctor = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard | CallingConventions.HasThis, new Type[0]);
var ilGenerator = ctor.GetILGenerator();

// i want to call the constructor of the baseclass with eventName as param
ilGenerator.Emit(OpCodes.Ldarg_0); // push "this"
ilGenerator.Emit(OpCodes.Ldstr, eventName); // push the param
ilGenerator.Emit(OpCodes.Call, baseCtor);
ilGenerator.Emit(OpCodes.Ret);

var type = typeBuilder.CreateType();

// return ...
}

在调用构造函数时,我得到了 BadImageFormatException。我做错了什么?

根据要求:

BaseClass 看起来像这样:

public abstract class GenericType<GT, TEventSource, TEventArgs> : BaseClass
where GT: GenericType<GT, TEventSource, TEventArgs>, new()
where TEventArgs : EventArgs
where TEventSource : class
{
protected GenericType(string eventName)
{
_eventName = eventName;
}
// ...
}

我希望在运行时得到什么结果:

public class MyType : BaseClass<MyType, ConcreteSourceType, ConcreteEventArgsType>
{
protected MyType() : base("SomeName")
{

}
}

最佳答案

我认为问题在于您正在尝试调用开放泛型类型的构造函数 GenericType<GT, TEventSource, TEventArgs> , 但你需要调用封闭类型的构造函数 BaseClass<MyType, ConcreteSourceType, ConcreteEventArgsType> .解决方案看起来很简单:

var baseCtor = baseType.GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance, null,
new[] { typeof(string) }, null);

问题是这不起作用并抛出 NotSupportedException .所以,它似乎得到了一个泛型类型的构造函数,其中一个参数是 TypeBuilder。支持螺母。

因此,我认为使用 Reflection.Emit 不可能实现您想要的,除非有一些 hack 来解决这个问题。

编辑啊哈!我不得不深入研究 Reflector 中的 Reflection.Emit(尽管查看文档中的正确位置也可以),但我发现:有一个特殊的正是为此的方法:the static TypeBuilder.GetConstructor() .所以这应该有效:

var baseNonGenericCtor = baseNotGenericType.GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance, null,
new[] { typeof(string) }, null);
var baseCtor = TypeBuilder.GetConstructor(baseType, baseNonGenericCtor);

关于c# - 动态创建类型并调用基类的构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10090350/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com