Почему для использования дженериков нужен интерфейс?

interface IPerson 
{
  string GetFirstName();
  string GetLastName();
}

class Speaker 
{
  public void SpeakTo<T>(T person) where T : IPerson 
  {
    string name = person.GetFirstName();
    this.say("Hello, " + name);
  }
}


Это пример из wiki, в статье обобщенное программирование.
Можете подробно объяснить, что делает этот код?
  • Вопрос задан
  • 233 просмотра
Решения вопроса 1
Вопрос конечно не совсем корректен, интерфейс не обязателен.

Вы просто в этом примере создаете интерфейс IPerson. Этот интерфейс могут по факту реализовывать сколько угодно классов. Например Person1, Person2, Person3. Все по своему.
Теперь вам нужно сделать метод SpeakTo, который позволит вам поговорить с любым из этих классов. Окей, пишем дженерик и пишем ограничение на интерфейс. (where T : IPerson )
Теперь в метод вы можете передать любой класс, реализующий интерфейс IPerson.

Но вы также можете написать например класс PersonBase вместо интерфейса, унаследовать наши Person1, Person2, Person3 от базового класса. Тогда вам нужно будет написать ограничение не на интерфейс, а на базовый класс where T : PersonBase. И вы также сможете передавать в метод SpeakTo любой класс, унаследованный от PersonBase.
public class PersonBase
{
  public virtual string GetFirstName() {return "MY name is base"; }
  public virtual string GetLastName() { return "MY lastname is base"; }
}

//либо через абстрактный класс
//public abstarct class PersonBase
//{
//  public abstract string GetFirstName();
//  public abstract string GetLastName();
//}

class Speaker 
{
  public void SpeakTo<T>(T person) where T : PersonBase
  {
    string name = person.GetFirstName();
    this.say("Hello, " + name);
  }
}

Еще бывают ограничения на конструктор, ограничения ссылочного типа и ограничения типа значения.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы