如果模板是List<>,则将变量视为List。

时间:2017-02-08 15:57:52

标签: c#

如果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?

1 个答案:

答案 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>>()