如何使用泛型类中的泛型类型的通用列表

时间:2011-03-11 15:50:31

标签: generics c#-4.0

在下面的示例控制台应用程序中,您会注意到该程序正在尝试创建一个篮球队,然后向该团队添加一名球员和一名教练。

应用程序的设计实现了具体类(Teamrs(),Player()和Coach())将继承的泛型类(Team和Person)。

程序在我尝试将Person对象添加到team.Members列表时抛出构建异常。

例外情况如下:

  

最佳重载方法匹配   'System.Collections.Generic.List> .Add(Person)'有一些无效   参数。

我不明白为什么当成员被定义为通用播放器的通用列表时,编译器不允许我将通用播放器(Kobe和Phil)添加到成员列表。

你能解释一下错误的原因以及如何解决它吗?

另外,您能否告诉我下面的示例程序是否通常不是我们应该如何实现泛型?换句话说,鉴于下面程序中的错误,我想知道为什么我应该实现泛型而不是坚持使用普通的抽象类。

顺便说一句,请不要仅仅因为你不喜欢湖人而进行投票;)

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>
    {
    }

3 个答案:

答案 0 :(得分:1)

为什么不呢:

//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
    {
    }

泛型的使用似乎完全没必要。简单的层次结构对你来说应该足够了。

答案 1 :(得分:1)

你似乎在混淆继承和泛型。虽然技术上有所不同,但您可以将通用类视为模板,而不是is-a关系。正常的继承就是你想要的。

答案 2 :(得分:1)

因为您将Team声明为类型为Lakers,将Person声明为类型Player。那些不相等。

你需要约束你的名单吗?你不能把它宣布为人吗?

abstract class Team<T>
    {
        public List<Person> Members = new List<Person>();
    }