Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 反射发出:如何为此构建构造函数_C#_Reflection_Reflection.emit_Typebuilder - Fatal编程技术网

C# 反射发出:如何为此构建构造函数

C# 反射发出:如何为此构建构造函数,c#,reflection,reflection.emit,typebuilder,C#,Reflection,Reflection.emit,Typebuilder,我要动态构建的代码如下所示: public class Sample { public Sample() { Items = new ObservableTestCollection<Sample>(this); } public Sample(IEnumerable<Sample> source) { Items = new ObservableTestCollection<Sample>

我要动态构建的代码如下所示:

public class Sample
{
    public Sample()
    {
        Items = new ObservableTestCollection<Sample>(this);
    }
    public Sample(IEnumerable<Sample> source)
    {
        Items = new ObservableTestCollection<Sample>(this, source);
    }
    public ObservableTestCollection<Sample> Items;
}
public class ObservableTestCollection<T> : ObservableCollection<T>
{
    public T Parent;       
    public ObservableTestCollection(T parent)
    {
        Parent = parent;
    }
    public ObservableTestCollection(T parent, IEnumerable<T> source) : base(source)
    {
        Parent = parent;
    }
}
我写的代码是:

const string assemblyName = "SampleAssembly";
const string fieldName = "Items";
const string typeName = "Sample";
const string assemblyFileName = assemblyName + ".dll";

AppDomain domain = AppDomain.CurrentDomain;
AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly(new AssemblyName(assemblyName), AssemblyBuilderAccess.RunAndSave);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName, assemblyFileName);

TypeBuilder typeBuilder = moduleBuilder.DefineType(typeName, TypeAttributes.Class | TypeAttributes.Public);

Type[] ctorParameters = new Type[] { typeBuilder };
Type typeOfCTS = typeof(ObservableTestCollection<>);
Type genericTypeOTS = typeOfCTS.MakeGenericType(typeBuilder);


FieldBuilder fieldBuilder = typeBuilder.DefineField(fieldName, genericTypeOTS, FieldAttributes.Public);

        //first constructor
ConstructorBuilder ctorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, Type.EmptyTypes);
ILGenerator generator = ctorBuilder.GetILGenerator();
        generator.Emit(OpCodes.Ldarg_0); //load this
        generator.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes)); //call object constructor

var ci = typeOfCTS.GetConstructors()[0];
generator.Emit(OpCodes.Newobj, ci);            
generator.Emit(OpCodes.Stfld, fieldBuilder); // store into Items
generator.Emit(OpCodes.Ret); //return

//second constructor
var typeOfIE = typeof(IEnumerable<>);
var genericTypeIE = typeOfIE.MakeGenericType(typeBuilder);          
ctorParameters = new Type[] {genericTypeIE };
ctorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, ctorParameters);

ctorParameters = new Type[] { typeBuilder, genericTypeIE };
generator = ctorBuilder.GetILGenerator();
generator.Emit(OpCodes.Ldarg_0); //load this

ci = typeOfCTS.GetConstructors()[1];
generator.Emit(OpCodes.Newobj, ci);
generator.Emit(OpCodes.Stfld, fieldBuilder); // store into Items
generator.Emit(OpCodes.Ret); //return
Type type = typeBuilder.CreateType();
var obj = Activator.CreateInstance(type);
assemblyBuilder.Save(assemblyFileName);
const string assemblyName=“samplessembly”;
常量字符串fieldName=“Items”;
常量字符串typeName=“Sample”;
常量字符串assemblyFileName=assemblyName+“.dll”;
AppDomain域=AppDomain.CurrentDomain;
AssemblyBuilder AssemblyBuilder=domain.definedDynamicAssembly(新的AssemblyName(AssemblyName),AssemblyBuilderAccess.RunAndSave);
ModuleBuilder ModuleBuilder=assemblyBuilder.DefinedDynamicModule(assemblyName,assemblyFileName);
TypeBuilder TypeBuilder=moduleBuilder.DefineType(typeName,TypeAttributes.Class | TypeAttributes.Public);
类型[]参数=新类型[]{typeBuilder};
TypeTypeOfcts=typeof(ObservableTestCollection);
Type genericTypeOTS=typeOfCTS.MakeGenericType(typeBuilder);
FieldBuilder FieldBuilder=typeBuilder.DefineField(fieldName、genericTypeOTS、FieldAttributes.Public);
//第一构造器
ConstructorBuilder-ctorBuilder=typeBuilder.DefineConstructor(MethodAttributes.Public,CallingConventions.HasThis,Type.EmptyTypes);
ILGenerator=ctorBuilder.GetILGenerator();
生成器.Emit(操作码.Ldarg_0)//装这个
Emit(opcode.Call,typeof(object).GetConstructor(Type.EmptyTypes))//调用对象构造函数
var ci=typeOfCTS.GetConstructors()[0];
生成器.Emit(操作码.Newobj,ci);
生成器.Emit(操作码.Stfld,fieldBuilder);//储存成物品
生成器.Emit(操作码.Ret)//返回
//第二构造器
var typeOfIE=typeof(IEnumerable);
var genericTypeIE=typeOfIE.MakeGenericType(typeBuilder);
ctorParameters=新类型[]{genericTypeIE};
ctorBuilder=typeBuilder.DefineConstructor(MethodAttributes.Public,CallingConventions.HasThis,ctorParameters);
ctorParameters=新类型[]{typeBuilder,genericTypeIE};
generator=ctorBuilder.GetILGenerator();
生成器.Emit(操作码.Ldarg_0)//装这个
ci=typeOfCTS.GetConstructors()[1];
生成器.Emit(操作码.Newobj,ci);
生成器.Emit(操作码.Stfld,fieldBuilder);//储存成物品
生成器.Emit(操作码.Ret)//返回
Type Type=typeBuilder.CreateType();
var obj=Activator.CreateInstance(类型);
assemblyBuilder.Save(assemblyFileName);
我无法创建示例的实例

有人能帮我纠正这个问题吗


非常感谢您的帮助。

您的程序无效,因为您试图创建一个实例“ObservateTestCollection of Sample”,但Sample是一个类型生成器


如果泛型参数是typebuilder而不是“MakeGenericType”,请使用获取泛型构造函数。

此错误的原因是调用了用于打开泛型类型的构造函数。您需要使用
TypeBuilder
作为泛型参数来获取封闭泛型类型的构造函数。 获取已解释的
构造函数信息
时存在一些问题

所以,解决方案是使用以下参数调用
TypeBuilder.GetConstructor(Type,ConstructorInfo)
static方法(正如前面提到的@TonyTHONG):

  • Type
    必须是在
    TypeBuilder
    上关闭的泛型类型,在您的例子中是
    typeof(observeTestCollection)。MakeGenericType(TypeBuilder)
  • ConstructorInfo
    ,您可以从opengeneric type中获得,在您的例子中是
    typeof(observeTestCollection)
您可以在下面看到问题的代码示例:

        const string assemblyName = "SampleAssembly";
        const string fieldName = "Items";
        const string typeName = "Sample";
        const string assemblyFileName = assemblyName + ".dll";

        var domain = AppDomain.CurrentDomain;
        var assemblyBuilder = domain.DefineDynamicAssembly(new AssemblyName(assemblyName), AssemblyBuilderAccess.RunAndSave);

        var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName, assemblyFileName);
        var typeBuilder = moduleBuilder.DefineType(typeName, TypeAttributes.Class | TypeAttributes.Public);

        var typeOfCts = typeof(ObservableTestCollection<>);
        var genericTypeOfCts = typeOfCts.MakeGenericType(typeBuilder);

        var fieldBuilder = typeBuilder.DefineField(fieldName, genericTypeOfCts, FieldAttributes.Public);

        //first constructor Sample()
        var ctorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, Type.EmptyTypes);
        var obsCtor1 = typeOfCts.GetConstructors().First(c => c.GetParameters().Length == 1);
        obsCtor1 = TypeBuilder.GetConstructor(genericTypeOfCts, obsCtor1); //hack to get close generic type ctor with typeBuilder as generic parameter

        var generator = ctorBuilder.GetILGenerator();
        generator.Emit(OpCodes.Ldarg_0); //load this for base type constructor
        generator.Emit(OpCodes.Call, typeof(object).GetConstructors().Single());

        generator.Emit(OpCodes.Ldarg_0); //load this for field setter

        generator.Emit(OpCodes.Ldarg_0); //load this for ObservableTestCollection constructor
        generator.Emit(OpCodes.Newobj, obsCtor1); //call ObservableTestCollection constructor, it will put point to new object in stack

        generator.Emit(OpCodes.Stfld, fieldBuilder); // store into Items
        generator.Emit(OpCodes.Ret); //return

        //second constructor Sample(IEnumerable<Sample> source)
        var ctorParam = typeof(IEnumerable<>).MakeGenericType(typeBuilder);
        ctorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new Type[] { ctorParam } );
        obsCtor1 = typeOfCts.GetConstructors().First(c => c.GetParameters().Length == 2);
        obsCtor1 = TypeBuilder.GetConstructor(genericTypeOfCts, obsCtor1); //hack to get close generic type ctor with typeBuilder as generic parameter

        generator = ctorBuilder.GetILGenerator();
        generator.Emit(OpCodes.Ldarg_0); //load this for base type constructor
        generator.Emit(OpCodes.Call, typeof(object).GetConstructors().Single());

        generator.Emit(OpCodes.Ldarg_0); //load this for field setter

        generator.Emit(OpCodes.Ldarg_0); //load this for ObservableTestCollection constructor
        generator.Emit(OpCodes.Ldarg_1); //load IEnumerable for ObservableTestCollection constructor
        generator.Emit(OpCodes.Newobj, obsCtor1); //call ObservableTestCollection constructor, it will put point to new object in stack

        generator.Emit(OpCodes.Stfld, fieldBuilder); // store into Items
        generator.Emit(OpCodes.Ret); //return


        var type = typeBuilder.CreateType();
        var obj1 = Activator.CreateInstance(type);

        var parameter = Activator.CreateInstance(typeof(List<>).MakeGenericType(type));
        var obj2 = Activator.CreateInstance(type, parameter);
        assemblyBuilder.Save(assemblyFileName);
const string assemblyName=“samplessembly”;
常量字符串fieldName=“Items”;
常量字符串typeName=“Sample”;
常量字符串assemblyFileName=assemblyName+“.dll”;
var domain=AppDomain.CurrentDomain;
var assemblyBuilder=domain.definedDynamicAssembly(新的AssemblyName(AssemblyName),AssemblyBuilderAccess.RunAndSave);
var moduleBuilder=assemblyBuilder.DefinedDynamicModule(assemblyName,assemblyFileName);
var typeBuilder=moduleBuilder.DefineType(typeName,TypeAttributes.Class | TypeAttributes.Public);
var typeOfCts=typeof(ObservableTestCollection);
var genericTypeOfCts=typeOfCts.MakeGenericType(typeBuilder);
var fieldBuilder=typeBuilder.DefineField(fieldName、genericTypeOfCts、FieldAttributes.Public);
//第一个构造函数示例()
var ctorBuilder=typeBuilder.DefineConstructor(MethodAttributes.Public,CallingConventions.HasThis,Type.EmptyTypes);
var obscortor1=typeOfCts.GetConstructors().First(c=>c.GetParameters().Length==1);
obsCtor1=TypeBuilder.GetConstructor(genericTypeOfCts,obsCtor1)//使用typeBuilder作为泛型参数来关闭泛型类型ctor
var generator=ctorBuilder.GetILGenerator();
生成器.Emit(操作码.Ldarg_0)//为基类型构造函数加载此
Emit(OpCodes.Call,typeof(object.GetConstructors().Single());
生成器.Emit(操作码.Ldarg_0)//为字段设置器加载此文件
生成器.Emit(操作码.Ldarg_0)//为ObservateTestCollection构造函数加载此
生成器.Emit(操作码.Newobj,obstrot1)//调用ObservateTestCollection构造函数,它将把点放到堆栈中的新对象
生成器.Emit(操作码.Stfld,fieldBuilder);//储存成物品
生成器.Emit(操作码.Ret)//返回
//第二个构造函数示例(IEnumerable源)
var-ctorParam=typeof(IEnumerable).MakeGenericType(typeBuilder);
ctorBuilder=typeBuilder.DefineConstructor(MethodAttributes.Public,CallingConventions.HasThis,新类型[]{ctorParam});
obsCtor1=typeOfCts.GetConstructors().First(c=>c.GetParameters().Length==2);
obsCtor1=TypeBuilder.GetConstructor(genericTypeOfCts,obsCtor1)//使用typeBuilder作为泛型参数来关闭泛型类型ctor
generator=ctorBuilder.GetILGenerator();
生成器.Emit(操作码.Ldarg_0)//为基类型构造函数加载此
生成器.Emit(操作码.C