类型参数约束是一个类

时间:2012-04-11 08:13:37

标签: c# generics inheritance interface covariance

我注意到其他开发人员使用这种技术,但它总是让我困惑。我今天早上决定进行调查,并在MSDN上发现了以下内容(来自http://msdn.microsoft.com/en-us/library/d5x73970(v=vs.100).aspx):

public class GenericList<T> where T : Employee
{
...
}

为什么我们要使用此方法而不是在类中用Employee替换T的所有实例?对我来说,这似乎是可维护性的胜利。我可以理解限制接口作为包含来自不同继承层次结构的类的方法,但是继承已经以更明显的方式解决了上面的问题,不是吗?

这可能被视为一个错误,或者修复&#39;像这样的代码?

4 个答案:

答案 0 :(得分:7)

因为它可能是从Employee派生的东西。

public class EvilEmployee : Employee {
    public Int32 Evilness { get; set; }
}

现在可以做......

GenericList<EvilEmployee> list = GetEvilEmployees();
var mostEvilEmployee = list.OrderByDescending(e => e.Evilness).First();

因为我们知道,在编译时,T = EvilEmployee并且EvilEmployee具有Evilness属性。如果我们要将列表强制转换为不可能的Employee列表(不使用OfType)。

答案 1 :(得分:5)

  

为什么我们要使用此方法而不是在类中用Employee替换T的所有实例?

启用:

class Manager : Employee { ... }

var board = new GenericList<Manager> ();

请注意,在这种情况下,您的名称“GenericList”更像是“EmployeeList”

  

我可以理解限制接口作为包含来自不同继承层次结构的类的方法

类继承和接口有很多共同之处。

  

但继承已经以更明显的方式解决了上述问题,不是吗?

是的,但不一样。 board.Add(lowlyProgrammer);将在此处失败,而继承将允许它。

答案 2 :(得分:0)

有意添加声明。想想有一些派生自Employee类的类的情况;如果没有定义泛型类,则需要为每个派生类定义一个类。

例如,如果EmployeeX继承了Employee,并且您希望定义仅接受EmployeeX实例的List,则通过使用泛型方法,您不需要定义新类。

答案 3 :(得分:0)

泛型允许您在不需要强制转换的情况下保持类型安全。

如果你有

  public class Manager : Employee
  {
     public double CalculateManagerBonus();
  }

你可以做到

   GenericList<Manager> managers = ....

   managers[0].CalculateManagerBonus();

如果你有

   GenericList<Employee> managers = ....

   // this is a compiler error
   managers[0].CalculateManagerBonus();

  // this is neccessary if there where no generics.
  ((Manager)managers[0]).CalculateManagerBonus();