如何构建构造函数
How to build constructor
构建构造函数对我来说并不容易
我正在尝试创建代码的第二个构造函数
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;
}
}
而我写的constructor builder如下:
//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);
谁能帮我找出我的代码有什么问题。
我发现问题不在于构建第二个构造函数,而在于创建泛型类型的实例。
我更新如下:
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 });
构建构造函数对我来说并不容易
我正在尝试创建代码的第二个构造函数
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;
}
}
而我写的constructor builder如下:
//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);
谁能帮我找出我的代码有什么问题。
我发现问题不在于构建第二个构造函数,而在于创建泛型类型的实例。
我更新如下:
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 });