不确定是否可行,但我希望能够根据List<T>
填充T
。目前,我有这样的事情(请原谅通用名称 - 它是出于测试目的):
public static class CollectionsClass
{
List<Object1> list1 = new List<Object1>();
List<Object2> list2 = new List<Object2>();
List<Object3> list3 = new List<Object3>();
}
public static class ActionClass
{
public static void PopulateCollections()
{
Populate(CollectionsClass.list1, 0, 10);
Populate(CollectionsClass.list2, 20, 50);
Populate(CollectionsClass.list3, 30, 100);
}
private static void Populate(dynamic list, int minLimit, int maxLimit)
{
var rnd = new Random();
int rndNum = rnd.Next(minLimit, maxLimit);
for (int i = 0; i < rndNum; i++)
{
if (list.GetType() == typeof(List<Object1>))
{
list.Add(new Object1());
}
else if (list.GetType() == typeof(List<Object2>))
{
list.Add(new Object2());
}
else if (list.GetType() == typeof(List<Object3>))
{
list.Add(new Object3());
}
else
{
// put out an error
}
}
}
}
虽然该代码有效,但我想通过执行以下操作来缩小它:
list.Add(new list.ObjectType());
我整天都在思考反思和获取类型,但我似乎无法想象这一点。
答案 0 :(得分:4)
不要使用动态,使用泛型:
static void Populate<T>(List<T> list, ...) where T: new()
{
...
for (int i=0; i<rndNum; i++)
list.Add(new T());
}
答案 1 :(得分:3)
由于您已经在使用dynamic
,因此您应该可以添加方法来处理此问题:
private static void AddToList<T>(List<T> list) where T : new()
{
list.Add(new T());
}
鉴于此,你可以写:
private static void Populate(dynamic list, int minLimit, int maxLimit)
{
var rnd = new Random();
int rndNum = rnd.Next(minLimit, maxLimit);
for (int i = 0; i < rndNum; i++)
{
AddToList(list);
}
}
答案 2 :(得分:2)
尝试使用通用方法:
public static class CollectionsClass
{
public static List<Object1> list1 = new List<Object1>();
public static List<Object2> list2 = new List<Object2>();
public static List<Object3> list3 = new List<Object3>();
}
public static class ActionClass
{
public static void PopulateCollections()
{
Populate(CollectionsClass.list1, 0, 10);
Populate(CollectionsClass.list2, 20, 50);
Populate(CollectionsClass.list3, 30, 100);
}
private static void Populate<T>(List<T> list, int minLimit, int maxLimit)
where T : new()
{
var rnd = new Random();
int rndNum = rnd.Next(minLimit, maxLimit);
for (int i = 0; i < rndNum; i++)
{
list.Add(new T());
}
}
}
答案 3 :(得分:1)
听起来你想要一系列泛型和反思。
void Populate<T>(List<T> mylist)
现在您知道列表的类型:它是T
。
剩下的就是循环并创建特定类型T
的实例。为此,您可以使用Activator.CreateInstance
:
for(int i = 0; i < 5; i++){
mylist.Add((T) Activator.CreateInstance(typeof(T)));
}
使用此示例代码:
void Main()
{
Populate<Type1>(new List<Type1>());
Populate<Type2>(new List<Type2>());
}
void Populate<T>(List<T> mylist){
for(int i = 0; i < 5; i++){
mylist.Add((T) Activator.CreateInstance(typeof(T)));
}
foreach(var item in mylist){
Console.WriteLine (item);
}
}
class Type1 { }
class Type2 { }
class Type3 { }
你得到这个输出:
这将依赖于反射来创建对象的实例,假设有一个公共非参数构造函数可用(否则将从Activator
抛出异常)。
这不是一个非常理想的行为,只要我看到在其泛型函数中使用where T : new()
约束的其他答案,我就会意识到这一点:使用此方法超过我的。
我仍然会把它留在这里以保持完整性(至少它表明了一个可能的陷阱)。
答案 4 :(得分:1)
您可以使用通用new
约束来实现此目的:
private static void PopulateList<T>(List<T> list, int minLimit, int maxLimit)
where T : new()
{
var rnd = new Random();
int rndNum = rnd.Next(minLimit, maxLimit);
for (int i = 0; i < rndNum; i++)
{
list.Add(new T());
}
}
约束是类型T必须提供默认构造函数。如果要将项添加到List,则不需要dynamic
关键字,因为您可以直接将List<T>
指定为参数类型。
如果您无法添加默认构造函数,还可以提供创建者函数:
private static void PopulateList<T>(List<T> list, Func<int, T> creatorFunc,
int minLimit, int maxLimit)
{
var rnd = new Random();
int rndNum = rnd.Next(minLimit, maxLimit);
for (int i = 0; i < rndNum; i++)
{
list.Add(creatorFunc(i));
}
}
你可以这样调用这个方法:
var lst = new List<MyObjectType>();
PopulateList<MyObjectType>(lst, x => new MyObjectType(x), 1, 7);
在此示例中,i
的值提供给creatorFunc,后者返回类型为MyObjectType
的新对象。
答案 5 :(得分:1)
使用factory来提取创建逻辑,使用反射来获取正确的类型,使用Activator来获取实例。
public static class TFactory
{
public static T Getmplementation<T>()
{
var typeName = typeof(T).Name;
var type = Type.GetType(typeName);
if (type != null)
return Activator.CreateInstance(type) as T;
else
throw new NotImplementedException(typeName);
}
}
然后,
List.Add(TFactory.GetImplmentation&LT;&#39; T&GT;());