如何在C#中一般实例化generics类?

也许这很简单,但我没有使用类型Type和它的用途。

假设我想用T = DoubleT = UInt32创建List ,具体取决于某些函数的结果,比如public static Type CheckType(String input);

在代码中:

 Type t = Program.CheckType(someInput); // it returns typeof(Double) or typeof(UInt32) if (t == typeof(Double)) List l = new List(); else List l = new List(); 

我知道上面的代码不会编译,因为我让l有两个不同的含义(一个double列表和一个unsigned int列表)……所以它引出了我的问题

  • 有没有办法在上面的代码中避免使用if

与此类似的东西:

 Type t = Program.CheckType(someInput); List l = new List(); // I know this won't compile either... 

我的意思是,这通常会实例化一个通用List …

先感谢您!

编辑:

不是 标记问题 的重复 ,只有一个原因: DoubleUInt32不是匿名类型! 这里的问题是如何确定某些输入数据的类型 (例如, Type T = typeof(Double)Type T = typeof(UInt32) ),因此, 创建一个基于 SampleClass 的通用 在那个输入数据类型上T

换句话说:在运行时确定一些Type T ,然后使用确定的类型T实例化generics类型。 对不起,如果我之前没有说清楚……

PS:我使用List作为SampleClass的示例。

您不能将列表键入为通用列表,因为您不知道类型参数,但可以在运行时创建List实例。

 Type t = Program.CheckType(someInput); Type listType = typeof(List<>).MakeGenericType(t); IList list = (IList) Activator.CreateInstance(listType); 

如果您尝试添加不正确类型的对象,您将获得exception,因此这种方法优于使用ArrayListList类的集合。

在这种情况下,没有真正的理由使用generics。 由于通用参数在编译时是未知的,因此编译器无法validation您尝试添加或删除的对象是否适合该列表。

如果可能的话,最好完全避免这种情况,可能是通过制作这个代码本身就是通用的方法。

如果那是不可能的,那么最好只使用非genericsArrayListList ,因为在此上下文中使用generics列表将添加许多额外的工作,无需额外帮助。

MakeGenricType可能有效

使用Reflection设置类型为List 的Property

  Type type = Program.CheckType(someInput); IList list = (IList) Activator.CreateInstance(typeof(List<>).MakeGenericType(type)); object obj = Activator.CreateInstance(type); list.Add(obj); 
 Type t = Program.CheckType(someInput); var l = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(t)); 

我会选择通用的Histogram但不要尝试将两种类型保存在同一个变量中,除非你想要一个IDictionary变量。

以下是使用double类型的直方图的示例:

 class Program { static Random rnd=new Random(); static void Main(string[] args) { Historgram hist=new Historgram(); for(int i=0; i<1000; i++) { double x=Math.Round(rnd.NextDouble(), 1); hist.Add(x); } //double[] values=hist.Values; Console.WriteLine("Histogram"); Console.WriteLine("{0,12} {1,12}", "Value", "Quantity"); for(int i=0; i<=10; i++) { double x=(i/10d); Console.WriteLine("{0,12} {1,12}", x, hist[x]); } Console.ReadLine(); } 

结果

  Histogram Value Quantity 0 52 0.1 97 0.2 117 0.3 98 0.4 93 0.5 110 0.6 97 0.7 94 0.8 98 0.9 93 1 51 

和代码:

 public class Historgram { Dictionary bins; public Historgram() { this.bins=new Dictionary(); } public void Add(T value) { if(bins.ContainsKey(value)) { bins[value]++; } else { bins.Add(value, 1); } } public void Remove(T value) { if(bins.ContainsKey(value)) { bins[value]--; if(bins[value]==0) { bins.Remove(value); } } } public int this[T x] { get { if(bins.ContainsKey(x)) { return bins[x]; } else { return 0; } } set { if(bins.ContainsKey(x)) { bins[x]=value; } else { bins.Add(x, value); } } } public bool ContainsValue(T value) { return bins.ContainsKey(value); } public int Count { get { return bins.Count; } } public T[] Values { get { return bins.Keys.ToArray(); } } public int[] Quantities { get { return bins.Values.ToArray(); } } }