1

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

假设我想List<T>T=DoubleT=创建一个UInt32,这取决于某些函数的结果,比如说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>();

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

  • 有没有办法避免if上面的代码?

与此类似的东西:

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

我的意思是,这通常会实例化一个通用列表......

先感谢您!

编辑:

这不是标记问题的重复,仅出于一个原因:并且不是匿名类型!这里的问题是如何确定某些输入数据的类型(例如,将是=或= ),从而基于该输入数据类型创建一个泛型,!DoubleUInt32Type Ttypeof(Double)Type Ttypeof(UInt32) SampleClass<T> T

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

PS:我List<T>SampleClass<T>.

4

5 回答 5

6

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

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

如果你尝试添加一个不正确类型的对象,你会得到一个异常,所以这种方法比使用像这样的集合有优势ArrayList,或者List<object>

于 2013-02-05T20:37:39.143 回答
2

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

如果可能的话,最好完全避免这种情况,可能通过使该代码本身具有通用性的方法。

如果这不可能,最好只使用非泛型ArrayList或 a List<object>,因为在这种情况下使用泛型列表会增加很多额外的工作而没有额外的帮助。

于 2013-02-05T20:31:26.230 回答
2

MakeGenricType可能有效

使用反射设置 List<CustomClass> 类型的属性

    Type type = Program.CheckType(someInput);
    IList list = (IList) Activator.CreateInstance(typeof(List<>).MakeGenericType(type));
    object obj = Activator.CreateInstance(type);
    list.Add(obj);
于 2013-02-05T20:37:14.537 回答
2
Type t = Program.CheckType(someInput);
var l = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(t)); 
于 2013-02-05T20:37:33.530 回答
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(); } }
}
于 2013-02-05T21:01:44.837 回答