2017-01-03 44 views
0

构建构造函数并不容易。如何构建构造函数

我试图使代码

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); 

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

+0

你有使用反射型工具来给你的C#示例的IL? – RQDQ

+0

我已经使用ILDASM,并没有其他工具。你有什么想法? –

+0

我使用Telerik JustDecompile:http://www.telerik.com/products/decompiler.aspx但我确定还有其他不错的选择。 – RQDQ

回答

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 }); 
相关问题