动态创建IList类型的新实例
我的申请正在处理IList。 不同用户定义类型的IList。 我想我可以使用reflection来查看IList包含的对象类型,然后创建该类型的新实例,然后将其添加到IList本身?
所以在任何时候我都可能正在处理
IList l;
我想创建一个新的Customer实例
Customer c = new Customer(0, "None")
然后将其添加到列表中
l.Add(c);
显然,在运行时动态执行此操作是问题的关键。 希望有人能给我一些指示。 谢谢brendan
试试这个:
public static void AddNewElement(IList l, int i, string s) { T obj = (T)Activator.CreateInstance(typeof(T), new object[] { i, s }); l.Add(obj); }
用法:
IList l = new List (); l.Add(new Customer(1,"Hi there ...")); AddNewElement(l, 0, "None");
(编辑):
然后尝试这个:
public static void AddNewElement2(IList l, int i, string s) { if (l == null || l.Count == 0) throw new ArgumentNullException(); object obj = Activator.CreateInstance(l[0].GetType(), new object[] { i, s }); l.Add(obj); }
如果你可以使用无参数构造函数并在之后设置属性,那么你可以使你的方法通用,如: –
void Process(IList list, int x, string y) where T : MyBase, new() { T t = new T(); tX = x; tY = y; list.Add(t); }
其中MyBase是暴露int和string属性的类的基础。 如果需要,可以使用接口而不是基类。
您可以使用Activator.CreateInstance
方法通过类型名称(作为字符串)或System.Type
的实例来调用类的构造函数。
我想你应该改变你的设计。 您可以使用抽象工厂模式 。 使用reflection会降低性能。
这是工厂的代码。
public abstract class MyStore { public abstract string Name { get; } public abstract void AddItem(int id, string name); }
如果抽象类没有代码,可以考虑使用接口。
然后创建Customer store。
public class CustomerStore : MyStore, IEnumerable { List list = new List (); public override string Name { get { return "Customer Store"; } } public override void AddItem(int id, string name) { list.Add(new Customer(id, name)); } public IEnumerator GetEnumerator() { return list.GetEnumerator(); } }
用法
foreach (MyStore store in List) store.AddItem(0, "None");
如果要考虑商店类型,请使用
switch (store.Name) { case "Customer Store": SomeMethod((CustomerStore)store); break; default: throw new WhatEverException(); }
您可以使用Type.GetGenericArguments方法返回generics类型IList
Type T = l.GetType ( ).GetGenericArguments ( ) [ 0 ]; ConstructorInfo ctor = T.GetConstructor ( new Type [ 2 ] { typeof ( int ), typeof ( string ) } ); System.Diagnostics.Debug.Assert ( ctor != null ); object instance = ctor.Invoke ( new object [ 2 ] { 0, "None" } );
是抱歉我应该提到我将要处理的对象集将有一个接受int和字符串的构造函数。
这里的一个大问题是:如果你不知道这种类型,你怎么知道如何制作新的? 并非世界上的每个类型都有一个带有int和字符串的构造函数。
获取IList类型的最佳方法是查看索引器的属性类型 !
var collectionType = targetList.GetType().GetProperty("Item").PropertyType; var constructor = collectionType.GetConstructor(Type.EmptyTypes); var newInstance = constructor.Invoke(null);