如何构建构造函数

时间:2017-01-03 04:08:00

标签: c# reflection.emit typebuilder

构建构造函数对我来说并不容易。

我正在尝试制作代码的第二个构造函数

 public class Sample
{        

    public Sample Parent { get; set; }      
    public Sample(Sample parent)
    {
        Parent = parent;
        Children = new ObservableTestCollection<Sample>(this);
    }      
    public Sample(Sample parent, IEnumerable<Sample> source)
    {
        Parent = parent;
        Children = new ObservableTestCollection<Sample>(this, source);
    }            
    public ObservableTestCollection<Sample> Children { get;  set; }
}

ObservableTestCollection的来源如下:

 public class ObservableTestCollection<T> : ObservableCollection<T>
{
    public T Parent;   
    public ObservableTestCollection(T parent):this(parent, Enumerable.Empty<T>())
    {         
    }
    public ObservableTestCollection(T parent, IEnumerable<T> source): base(source) 
    {
      Parent = parent;
    }
}

我写的构造函数构建器如下:

        //first constructor           
        var obsCtor1 = typeOfCts.GetConstructors().First(c => c.GetParameters().Length == 1);
        obsCtor1 = TypeBuilder.GetConstructor(genericTypeOfCts, obsCtor1);
        var constructorParameters = new Type[] { typeBuilder };
        var ctorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, constructorParameters);
        il = ctorBuilder.GetILGenerator();
        il.Emit(OpCodes.Ldarg_0);
        il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
        il.Emit(OpCodes.Ldarg_0);
        il.Emit(OpCodes.Ldarg_1);
        il.Emit(OpCodes.Call, setParentMethod);
        il.Emit(OpCodes.Ldarg_0);
        il.Emit(OpCodes.Ldarg_0);
        il.Emit(OpCodes.Newobj, obsCtor1);
        il.Emit(OpCodes.Call, setChildrenMethod);
        il.Emit(OpCodes.Ret);


        //second constructor
             var obsCtor2 = typeOfCts.GetConstructors().First(c => c.GetParameters().Length == 2);
        obsCtor2 = TypeBuilder.GetConstructor(genericTypeOfCts, obsCtor2);
        var ctorParam = typeOfCts.MakeGenericType(typeBuilder);         
        constructorParameters = new Type[] { typeBuilder, ctorParam };          
        ctorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, constructorParameters);
        il = ctorBuilder.GetILGenerator();
        il.Emit(OpCodes.Ldarg_0);
        il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
        il.Emit(OpCodes.Ldarg_0);
        il.Emit(OpCodes.Ldarg_1);
        il.Emit(OpCodes.Call, setParentMethod);
        il.Emit(OpCodes.Ldarg_0);
        il.Emit(OpCodes.Ldarg_0);
        il.Emit(OpCodes.Ldarg_2);
        il.Emit(OpCodes.Newobj, obsCtor2);
        il.Emit(OpCodes.Call, setChildrenMethod);
        il.Emit(OpCodes.Ret);

        Type type = typeBuilder.CreateType();
        var obj1 = Activator.CreateInstance(type, new object[] { null });
        var obj2 = Activator.CreateInstance(type, obj1);
        assemblyBuilder.Save(assemblyFileName);

        var children = (IList)obj2.GetType().GetProperty(selfRefDerivedCollectionName).GetValue(obj2, null);
        ((INotifyCollectionChanged)children).CollectionChanged += Program_CollectionChanged;

        var obj3 = Activator.CreateInstance(type, new object[] { null });
        children.Add(obj3);


        var listOf = typeof(List<>);
        var listOfType = listOf.MakeGenericType(type);
        var list =(IList) Activator.CreateInstance(listOfType);
        obj1 = Activator.CreateInstance(type, new object[] { null });
        list.Add(obj1);
        obj1 = Activator.CreateInstance(type, new object[] { null });
        list.Add(obj1);
        var obj4 = Activator.CreateInstance(type, list);

有人可以帮助我找出我的代码有什么问题。

1 个答案:

答案 0 :(得分:0)

我发现问题不在于构建第二个构造函数,而是在制作泛型类型的实例。

我更新如下:

        Type type = typeBuilder.CreateType();
        var obj1 = Activator.CreateInstance(type, new object[] { null });
        var obj2 = Activator.CreateInstance(type, obj1);
        assemblyBuilder.Save(assemblyFileName);

        var children = (IList)obj2.GetType().GetProperty(selfRefDerivedCollectionName).GetValue(obj2, null);
        ((INotifyCollectionChanged)children).CollectionChanged += Program_CollectionChanged;

        var obj3 = Activator.CreateInstance(type, new object[] { null });
        children.Add(obj3);

        var genericType = typeOfCts.MakeGenericType(type);


        var list = Activator.CreateInstance(genericType, new object[] { null});
        obj1 = Activator.CreateInstance(type, new object[] { null });

        list.GetType().GetMethod("Add").Invoke(list, new object[] { obj1 });


        obj1 = Activator.CreateInstance(type, new object[] { null });
        list.GetType().GetMethod("Add").Invoke(list, new object[] { obj1 });

        var obj4 = Activator.CreateInstance(type, new object[] { null, list });
相关问题