2017-01-03 12 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

Вы использовали инструмент типа отражателя, чтобы дать вам IL вашего C#, например? – 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 });