如果template是List,我必须创建填充数据的List。我有一个功能
static T GenerateRandomFields<T>() where T:new()
{
var ret= new T();
if (typeof(T)==typeof(List<>))
{
var leng = rnd.Next(50);
List<typeof(T).GenericTypeArguments[0]> test;
for (int i = 0; i < leng; i++)
((List<>)ret).Add(...);
return ret;
}
...
}
但是不可能将Ret转换为List。如何将数据添加到ret?
答案 0 :(得分:0)
据我所知,你必须使用反射。当您在编译期间知道类型参数时,您将创建一个简单的通用方法:
public static IList<T> GenerateRandomList<T>() where T : new() {
var list = new List<T>();
var rnd = new Random();
var leng = rnd.Next(50);
for (var i = 0; i < Math.Max(leng, 1); i++) {
var newItem = new T();
list.Add(newItem);
}
return list;
}
现在,您必须将此方法与现有方法相关联。首先,您需要MethodInfo
指向泛型方法(我的类名为Q42117838
):
static MethodInfo genericMethod = typeof(Q42117838).GetMethod(nameof(GenerateRandomList));
其次,我们将为我们用实际列表类型调用的方法声明一个缓存:
static Dictionary<Type, MethodInfo> methods = new Dictionary<Type, MethodInfo>();
我们可以把它放在一起:
public static T GenerateRandomFields<T>() where T : new() {
if (typeof(System.Collections.IList).IsAssignableFrom(typeof(T))) {
var listType = typeof(T).GenericTypeArguments[0];
MethodInfo method;
if (!methods.TryGetValue(listType, out method))
methods.Add(listType, method = genericMethod.MakeGenericMethod(listType));
return (T)method.Invoke(null, new object[0]);
}
return default(T);
}
请注意测试
if (typeof(T)==typeof(List<>))
无效并且似乎没有简单的方法可以检查通用IList<>
(请参阅this question),因此我使用了非通用变体工作
现在您可以选择,请致电:
var x = Q42117838.GenerateRandomList<int>()
(首选,因为您在编译时知道类型)var x = Q42117838.GenerateRandomFields<List<int>>()