Sprague
Sprague

Reputation: 1638

Type Parameter Constraint is a Class

I've noticed other developers using this technique, but it always confused me. I decided to investigate this morning and came across the following on MSDN (from http://msdn.microsoft.com/en-us/library/d5x73970(v=vs.100).aspx):

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

Why would we want to use this method instead of replacing all instances of T with Employee in the class? To me, this seems like a win on maintainability. I can understand restricting to an interface as a means of including classes from different inheritance hierarchies, but inheritance already solves the problem above in a more obvious way, doesn't it?

Could this be considered a mistake, or would it be a mistake to 'fix' code like this?

Upvotes: 4

Views: 130

Answers (4)

k3b
k3b

Reputation: 14755

The generics allow you to be typesafe without the need to cast.

if you have

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

you can do

   GenericList<Manager> managers = ....

   managers[0].CalculateManagerBonus();

if you have

   GenericList<Employee> managers = ....

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

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

Upvotes: 0

Henk Holterman
Henk Holterman

Reputation: 273244

Why would we want to use this method instead of replacing all instances of T with Employee in the class?

To enable:

class Manager : Employee { ... }

var board = new GenericList<Manager> ();

Note that your name 'GenericList' would in this scenario be more like 'EmployeeList'

I can understand restricting to an interface as a means of including classes from different inheritance hierarchies

Class inheritance and interfaces have much in common.

but inheritance already solves the problem above in a more obvious way, doesn't it?

Yes, but it's not the same. board.Add(lowlyProgrammer); will fail here while inheritance would allow it.

Upvotes: 5

daryal
daryal

Reputation: 14919

Where statement is added on purpose. Think of a situation where there are classes deriving from Employee class; if you do not define a generic class, you need to define a class for each derived class.

For instance, if EmployeeX inherits Employee, and you want to define a List only accepting EmployeeX instances, by using the generic approach you do not need to define a new class.

Upvotes: 0

sisve
sisve

Reputation: 19781

Because it could be something derived from Employee.

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

It's now possible to do...

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

It's possible since we know, at compile time, that T = EvilEmployee and that EvilEmployee has an Evilness property. If we were to force the list into a list of Employee that wouldn't be possible (without using OfType).

Upvotes: 8

Related Questions