也许这很简单,但我没有使用类型Type
并且它正在使用。
我想创建List<T>
T
= Double
或T
= UInt32
,具体取决于某些功能的结果,例如{ {1}}
在代码中:
public static Type CheckType(String input);
我知道上面的代码不会编译,因为我让Type t = Program.CheckType(someInput); // it returns typeof(Double) or typeof(UInt32)
if (t == typeof(Double))
List<Double> l = new List<Double>();
else
List<UInt32> l = new List<UInt32>();
有两个不同的含义(一个double列表和一个unsigned int列表)...所以它会导致我的问题:
l
?类似的东西:
if
我的意思是,这通常会实例化一个通用的List ...
提前谢谢!
修改
marked question的不重复只有一个原因:Type t = Program.CheckType(someInput);
List<t> l = new List<t>(); // I know this won't compile either...
和Double
不是匿名类型!这里的问题是如何确定某些输入数据的类型(将UInt32
= Type T
或typeof(Double)
= Type T
,例如)因此,根据输入数据类型创建通用 typeof(UInt32)
,SampleClass<T>
!
换句话说:在运行时中确定一些T
,然后使用确定的类型Type T
实例化泛型类型。对不起,如果我之前没有说清楚......
PS:我使用T
作为List<T>
的示例。
答案 0 :(得分:6)
您不能将列表键入为通用列表,因为您不知道类型参数,但可以在运行时创建List实例。
Type t = Program.CheckType(someInput);
Type listType = typeof(List<>).MakeGenericType(t);
IList list = (IList) Activator.CreateInstance(listType);
如果您尝试添加不正确类型的对象,则会出现异常,因此此方法优于使用ArrayList
或List<object>
答案 1 :(得分:2)
在这种情况下没有真正的理由使用泛型。由于通用参数在编译时是未知的,因此编译器无法验证您尝试添加或删除的对象是否适合该列表。
如果可能的话,最好完全避免这种情况,可能是通过制作此代码本身通用的方法。
如果那是不可能的,那么使用非通用ArrayList
或List<object>
可能会更好,因为在此上下文中使用通用列表会增加许多额外的工作,无需额外的帮助
答案 2 :(得分:2)
MakeGenricType可能会有效
Using Reflection to set a Property with a type of List<CustomClass>
Type type = Program.CheckType(someInput);
IList list = (IList) Activator.CreateInstance(typeof(List<>).MakeGenericType(type));
object obj = Activator.CreateInstance(type);
list.Add(obj);
答案 3 :(得分:2)
Type t = Program.CheckType(someInput);
var l = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(t));
答案 4 :(得分:2)
我会选择通用Histogram<T>
,但不要尝试将两种类型保存在同一个变量中,除非您只想拥有IDictionary
变量。
以下是使用double
类型的直方图的示例:
class Program
{
static Random rnd=new Random();
static void Main(string[] args)
{
Historgram<double> hist=new Historgram<double>();
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<T>
{
Dictionary<T, int> bins;
public Historgram()
{
this.bins=new Dictionary<T, int>();
}
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(); } }
}