1

关于泛型类类型,我有一些不明白的地方需要向我解释。

我们以下面这个傻方法为例:

    public List<> RandomList()  //Note that the Compiler yells at you for not giving a type parameter
    {
        var RandObj = new Random();
        var myint = RandObj.Next(1,3);

        switch(myint)
        {
            case 1: var StringList = new List<string>{ "Test" };
                return StringList;

            case 2: var IntList = new List<int>{ 1,2,3,4 };
                return IntList;
        }
    }

无论如何要使这样的功能起作用吗?我想知道是否有办法设置它,以便我说。“这个函数返回一个列表。我不确定它会返回什么类型的列表,但它肯定是一个列表。

4

5 回答 5

4

为此,您必须返回一个类型,该类型对于您的返回对象可能是的所有可能选项都是通用的,对于这两个列表,您可以返回针对这种情况的最佳可能选项是IList

public IList RandomList()
{
    var RandObj = new Random();
    var myint = RandObj.Next(1,3);
    switch(myint)
    {
        case 1: var StringList = new List<string>{ "Test" };
            return StringList;

        case 2: var IntList = new List<int>{ 1,2,3,4 };
            return IntList;
    }
}

其他一些可能的选择是objectIEnumerableICollection

于 2013-10-13T02:42:09.930 回答
3

原则上,在 C# 语言中,如指定的那样,您不能这样做。

见 K.4.2 开式和闭式(Extracted Relevant Paragraph)

在运行时,泛型类型声明中的所有代码都在封闭构造类型的上下文中执行,该封闭构造类型是通过将类型参数应用于泛型声明而创建的。泛型类型中的每个类型参数都绑定到特定的运行时类型。所有语句和表达式的运行时处理总是发生在封闭类型中,而开放类型只发生在编译时处理期间。

编译器需要能够将所有开放类型转换为封闭类型。因此它抱怨。

如果你想要一个一致的外部视图,那么接口就是你要走的路。在这里IList会很好地工作。

于 2013-10-13T02:42:27.777 回答
0

虽然无法使用您无法控制的泛型类型,但只要您可以控制对象层次结构,就可以执行类似的操作。

考虑以下定义:

public class Number { };
public class Number<T>: Number {};

public static class NumberGenerator {

   public static Number Generate ( double value ) { return new Number<double>(); }
   public static Number Generate ( int value ) { return new Number<int>(); }

}

虽然很傻,但它确实满足了您概述的要求。虽然它实际上只是标准的多态性。

于 2013-10-13T05:43:34.713 回答
0

没有。 List<>是泛型类型定义,但不是真正的类型,因为它只能用于反射目的。它们应该被称为 C++ 中的模板:P

于 2013-10-13T02:41:53.867 回答
0

总的来说,我同意 SH- 的观点,因为 C# 并不是专门为此而设计的。你可以伪造这个(不完美)

    public IList<T> RandomList<T>() {
        T targetType = default(T);
        var RandObj = new Random();
        switch(targetType.GetType().Name) {
            case "String": 
                var StringList = new List<string>{ "Test" };
                return (IList<T>) StringList;

            case "Int32": 
                var IntList = new List<int>{ 1,2,3,4 };
                return (IList<T>) IntList;

            default:
                return null;
            }
        }

这样做意味着您必须考虑在编译时将与该类一起使用的所有泛型类型。您也可以使用“动态”类型来执行此操作。

于 2013-10-13T02:49:02.347 回答