代码之家  ›  专栏  ›  技术社区  ›  Ahmed

为什么这在C#泛型中不可能?

  •  7
  • Ahmed  · 技术社区  · 16 年前

    一位同事给我指出了C#中的一个奇怪案例(但不确定这是否真的奇怪)。

    List<Employee> x = new List<Employee>;
    

    我知道我需要将Employee类型传递给泛型列表,以便它知道有关Employee的必需类型信息,并生成返回和接受与Employee兼容的参数的方法。

    现在我的问题是,为什么不可能做到以下几点?

    Employee x = new Employee();
    List<typeof(x)> list = new List<typeof(x)>();
    

    这难道不足以满足列表所需的信息吗<&燃气轮机;要知道,为了创建一个列表?换句话说,x的类型(员工的类型)现在作为泛型类型参数传递给List<>,这(正如我过去所认为的)与传递list类型名称(在本例中为Employee)相同。

    我知道类似的东西在Java中是可用的(使用 .class )变量上的关键字。

    我肯定我错过了什么,所以请告诉我,伙计们!

    6 回复  |  直到 16 年前
        1
  •  30
  •   Jon Skeet    16 年前

    不,相当于这个 提供Java版本。不能使用“x.class”获取声明的变量类型。

    此外 typeof(x) Type 参考 姓名,例如。 typeof(string) 将返回对 类型 与 System.String 类型。这相当于使用 String.class 在Java中(请再次注意,这是适用的 .class 对于类型名称, 不 变量名。)

    Java泛型也不支持类似于final语句的任何东西。如果您认为他们会,请提供一个样本:)

    你呢 可以 C#中的do是使用类型推断来执行您想要的操作:

    public static List<T> CreateListForSampleType<T>(T sample)
    {
        return new List<T>();
    }
    
    ...
    
    Employee x = new Employee();
    var list = CreateListForSampleType(x);
    

    不能 被扩展以允许类似于 typeof(variablename) 或 List<typeof(variablename)>

        2
  •  2
  •   Håvard S    16 年前

    原因是typeof()返回一个type对象,而您需要一个type名称来在编译时初始化列表。

        3
  •  2
  •   Morfildur    16 年前

    Employee x = EmployeeFactory.NewEmployee("John Doe"); // Returns TraineeEmployee, Employee or ManagementEmployee;
    
    List<typeof(x)> l = new List<typeof(x)> l(); // What type is it?
    

        4
  •  1
  •   Daren Thomas    16 年前

    typeof 与类名一起使用。使用 GetType() 在对象上,但仅在运行时。。。

        5
  •  1
  •   Dercsár    16 年前

    您缺少的是编译时的静态类型引用和运行时的二进制类型引用(通过System.type实例)之间的区别。

    我希望这能说明问题。

    Jon Skeet上面的代码很酷。

        6
  •  0
  •   George Polevoy    16 年前

    找不到创建空列表的原因,因为C#3.0。

    我通常只使用IEnumerable中的ToList方法创建列表实例,而IEnumerable又使用yield-return、Concat()、Repeat()、Where()等生成。

    var list = CreateEmployees().ToList();
    

    ,

    public IEnumerable<Employee> CreateEmployees()
    {
     yield return new Employee("Foo");
     yield return new Employee("Bar");
    }