Как работать с универсальным списком универсального типа в универсальном классе - PullRequest
0 голосов
/ 11 марта 2011

В приведенном ниже примере консольного приложения вы заметите, что программа пытается создать баскетбольную команду, а затем добавить в команду игрока и тренера.

В проекте реализованы универсальные классы (Team и Person), которые будут наследовать конкретные классы (Lakers (), Player () и Coach ()).

Программа генерирует исключения сборки в тот момент, когда я пытаюсь добавить объект Person в список team.Members.

Исключение гласит:

Лучший перегруженный метод соответствует 'System.Collections.Generic.List> .Add (Person)' имеет некоторые недопустимые аргументы.

Я не понимаю, почему компилятор не позволяет мне добавлять универсальный проигрыватель (Кобе и Фил) в список участников, когда члены определены как универсальный список универсального проигрывателя.

Можете ли вы объяснить причину ошибки и как ее обойти?

Кроме того, можете ли вы сообщить мне, не является ли приведенный ниже пример программы типичным образом, как мы должны реализовывать дженерики? Другими словами, учитывая ошибки в приведенной ниже программе, меня удивляет, почему я должен реализовывать дженерики, а не придерживаться обычного абстрактного класса.

Кстати, пожалуйста, не отказывайтесь от голосования просто потому, что вам не нравятся Лейкерс;)

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 ]

1 голос
/ 11 марта 2011

Вы, кажется, смешиваете наследование и дженерики. Хотя это технически отличается, вы можете видеть универсальный класс как шаблон, а не как отношение is-a. Нормальное наследование - это все, что вам нужно.

1 голос
/ 11 марта 2011

Потому что вы объявляете Team как тип Lakers, а Person как тип Player. Те не равны.

Вам нужно ограничить свой список? Вы не можете просто объявить это как Персона?

abstract class Team<T>
    {
        public List<Person> Members = new List<Person>();
    }
1 голос
/ 11 марта 2011

Почему бы просто:

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

Использование генериков кажется совершенно ненужным. вам должно хватить простой иерархии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...