动态创建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);