如何在C#中泛型地实例化泛型类?
也许它很简单,但我不使用type如何在C#中泛型地实例化泛型类?,c#,generics,instantiation,C#,Generics,Instantiation,也许它很简单,但我不使用typetype和它的用法 假设我想用T=Double或T=UInt32创建一个列表,具体取决于某些函数的结果,比如公共静态类型检查类型(字符串输入) 代码: Type t = Program.CheckType(someInput); // it returns typeof(Double) or typeof(UInt32) if (t == typeof(Double)) List<Double> l = new List<Double&g
type
和它的用法
假设我想用T
=Double
或T
=UInt32
创建一个列表,具体取决于某些函数的结果,比如公共静态类型检查类型(字符串输入)代码>
代码:
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
和UInt32
不是匿名类型!这里的问题是如何确定一些输入数据的类型(例如,类型T
=typeof(Double)
或类型T
=typeof(UInt32)
),从而基于该输入数据类型创建一个通用的
,T
换句话说:在运行时确定一些类型T
,然后用确定的类型T
实例化泛型类型。对不起,如果我之前没有说清楚
PS:我使用了List
作为SampleClass
的一个例子,在这种情况下没有真正的理由使用泛型。由于泛型参数在编译时未知,编译器无法验证您尝试添加或删除的对象是否适合该列表
如果可能的话,最好完全避免这种情况,可能是通过使该代码本身具有泛型的方法
如果这是不可能的,那么最好只使用非泛型的ArrayList
或列表
,因为在这种情况下使用泛型列表会增加很多额外的工作,而无需额外的帮助。在这种情况下没有真正的理由使用泛型。由于泛型参数在编译时未知,编译器无法验证您尝试添加或删除的对象是否适合该列表
如果可能的话,最好完全避免这种情况,可能是通过使该代码本身具有泛型的方法
如果不可能,那么最好只使用非泛型的ArrayList
或列表,因为在此上下文中使用泛型列表将添加大量额外工作,而无需额外帮助。可能有效
Type Type=Program.CheckType(someInput);
IList list=(IList)Activator.CreateInstance(typeof(list).MakeGenericType(type));
object obj=Activator.CreateInstance(类型);
列表。添加(obj);
可能有效
Type Type=Program.CheckType(someInput);
IList list=(IList)Activator.CreateInstance(typeof(list).MakeGenericType(type));
object obj=Activator.CreateInstance(类型);
列表。添加(obj);
类型t=程序。检查类型(someInput);
var l=(IList)Activator.CreateInstance(typeof(List).MakeGenericType(t));
类型t=程序。检查类型(someInput);
var l=(IList)Activator.CreateInstance(typeof(List).MakeGenericType(t));
由于不知道type参数,因此不能将列表键入为泛型,但可以在运行时创建列表实例
Type t = Program.CheckType(someInput);
Type listType = typeof(List<>).MakeGenericType(t);
IList list = (IList) Activator.CreateInstance(listType);
Type t=Program.CheckType(someInput);
Type listType=typeof(List).MakeGenericType(t);
IList list=(IList)Activator.CreateInstance(listType);
如果尝试添加类型不正确的对象,则会出现异常,因此这种方法比使用集合(如ArrayList
)或List
)具有优势,因为您不知道类型参数,所以不能将列表键入为泛型,但可以在运行时创建列表实例
Type t = Program.CheckType(someInput);
Type listType = typeof(List<>).MakeGenericType(t);
IList list = (IList) Activator.CreateInstance(listType);
Type t=Program.CheckType(someInput);
Type listType=typeof(List).MakeGenericType(t);
IList list=(IList)Activator.CreateInstance(listType);
如果您试图添加一个类型不正确的对象,您将得到一个异常,因此这种方法比使用像ArrayList
或List
这样的集合有优势,我会选择一个通用的直方图
,但不尝试将这两种类型保存在同一个变量中,除非您只想要一个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();
}
以及守则:
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(); } }
}
公共类历史图表
{
字典箱;
公共直方图()
{
this.bins=新字典();
}
公共无效添加(T值)
{
if(容器箱(价值))
{
箱子[价值]+;
}
其他的
{
箱子。增加(价值,1);
}
}
公共无效删除(T值)
{
if(容器箱(价值))
{
箱子[价值]——;
如果(料仓[值]==0)
{
垃圾箱。移除(价值);
}
}
}
公共int-this[tx]
{
得到
{
if(集装箱箱(x))
{
回收箱[x];
}
其他的
{
返回0;
}
}
设置
{
if(集装箱箱(x))
{
箱子[x]=数值;
}
其他的
{
箱子。添加(x,值);
}
}
}
public bool ContainsValue(T value){return bins.ContainsKey(value);}
公共整数计数{get{return bins.Count;}
公共T[]值{get{return bins.Keys.ToArray();}
public int[]数量{get{return bins.Values.ToArray();}
}
我会选择一个通用的直方图
,但不会尝试将这两种类型保存在同一个变量中,除非您只想要一个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(); } }
}