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