How to work with a Generic List of a Generic Type in a Generic Class
In the example console app below, you will notice that the program is attempting to create a basketball team and, then, add a player and a coach to the team.
The design of the application implements generic classes (Team and Person) which concrete classes (Lakers(), Player(), and Coach()) will inherit.
The program throws build exceptions at the point where I attempt to add the P开发者_如何学编程erson object to the team.Members list.
The exception reads:
The best overloaded method match for 'System.Collections.Generic.List>.Add(Person)' has some invalid arguments.
I don't understand why the compiler doesn't allow me to add the generic Player (Kobe and Phil) to the Members list when Members is defined as a generic list of a generic Player.
Can you explain the cause of the error and how to work around it?
Also, can you fill me in on whether or not the example program below is not typically how we should be implementing generics? In other words, given the errors in the program below, it makes me wonder why I should implement generics and not stick with a normal abstract class.
By the way, please don't down-vote simply because you don't like the Lakers ;)
class Program
{
static void Main(string[] args)
{
//Create a team
Team<Lakers> team = new Lakers();
//Create a player then add the player to the list of team members
Person<Player> p = new Player();
p.Name = "Kobe";
team.Members.Add(p); //Invalid argument exception here
//Create a coach then add the coach to the list of team members
Person<Coach> c = new Coach();
c.Name = "Phil";
team.Members.Add(c); //Invalid argument exception here
//Display the members of the team
team.Members.ForEach(n => Console.WriteLine(n.Name));
Console.ReadLine();
}
}
//A generic class containing a generic list of a generic type
abstract class Team<T>
{
public List<Person<T>> Members = new List<Person<T>>();
}
//A concrete basketball team
class Lakers : Team<Lakers>
{
}
//A generic class that represents a person
abstract class Person<T>
{
public string Name { get; set; }
}
//A concrete person that represents a basketball player
class Player : Person<Player>
{
}
//A concrete person that represents a basketball coach
class Coach : Person<Coach>
{
}
Because you declare Team as type Lakers and Person as type Player. Those are not equal.
Do you need to constrain your List with ? Can't you just declare it as Person?
abstract class Team<T>
{
public List<Person> Members = new List<Person>();
}
Why not just:
//An abstract class that represents a person
abstract class Person
{
public string Name { get; set; }
}
//A concrete person that represents a basketball player
class Player : Person
{
}
//A concrete person that represents a basketball coach
class Coach : Person
{
}
The usage of generics seems totally unnecessary. the simple hierarchy should be enough for you.
You seem to be mixing up inheritance and generics. While technically different, you can see a generic class as template, and not as an is-a relationship. Normal inheritance is all you want here.
精彩评论