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

时间:2013-02-05 20:28:15

标签: c# generics instantiation

也许这很简单,但我没有使用类型Type并且它正在使用。

我想创建List<T> T = DoubleT = 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 Ttypeof(Double) = Type T,例如)因此,根据输入数据类型创建通用 typeof(UInt32) SampleClass<T>

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

PS:我使用T作为List<T>的示例。

5 个答案:

答案 0 :(得分:6)

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

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

如果您尝试添加不正确类型的对象,则会出现异常,因此此方法优于使用ArrayListList<object>

等集合

答案 1 :(得分:2)

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

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

如果那是不可能的,那么使用非通用ArrayListList<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(); } }
}