Создание обобщенных базовых классов

Создание обобщенных базовых классов

Перед рассмотрением обобщенных интерфейсов следует указать на то, что обобщенные классы могут быть базовыми для других классов и могут таким образом определять любое число виртуальных и абстрактных методов. Однако производные типы должны подчиняться определенным правилам, вытекающим из природы обобщенной абстракции. Во-первых, если обобщенный класс расширяется необобщенным, то производный класс должен конкретизировать параметр типа,

// Предположим, что создан пользовательский

// обобщенный класс списка.

public class MyList‹T› {

 private List‹T› listOfData = new List‹T›();

}

// Конкретные типы должны указать параметр типа,

// если они получаются из обобщенного базового класса.

public class MyStringList: MyList‹string› {}

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

// Обобщенный класс с виртуальным методом.

public class MyList‹T› {

 private List‹T› listOfData = new List‹T›();

 public virtual void PrintList(T data) {}

}

public class MyStringList: MyList‹string› {

 // В производных методах нужно заменить параметр типа,

 // используемый а родительском классе.

 public override void PrintList(string data) {}

}

Если производный тип тоже является обобщенным, дочерний класс может (опционально) использовать заменитель типа в своем определении. Однако знайте, что любые ограничения, размещенные в базовом классе, должны "учитываться" и производным типом. Например:

// Обратите внимание, теперь здесь имеется ограничение,

// требующее конструктор по умолчанию.

public class MyList‹T› where T: new() {

 private List‹T› listOfData = new List‹T›();

 public virtual void PrintList(T data) {}

 // Производный тип должен учитывать ограничения базового.

 public class MyReadOnlyList‹T›: MyList‹T› where T: new() {

  public override void PrintList(T data) {}

}

Если вы только не планируете построить свою собственную библиотеку обобщений, вероятность того, что вам придется строить иерархии обобщенных классов, оказывается практически нулевой. Тем не менее, вы теперь знаете, что язык C# обеспечивает поддержку наследования обобщений.