Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C#中泛型地实例化泛型类?_C#_Generics_Instantiation - Fatal编程技术网

如何在C#中泛型地实例化泛型类?

如何在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
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(); } }
}