Обобщения и наследование

Обобщенные типы С# не могут напрямую наследоваться от параметра типа. Однако можно использовать следующие параметры типа для конструирования базовых типов, которые они могут наследовать:

1
2
3
4
5
6
7
8
// Это неправильно!
public class MyClass<t> : Т
{
}
//А это правильно.
public class MyClass<t> : Stack<t>
{
}

В шаблонах С++ прямое наследование от параметра типа обеспечивает особую гибкость. Если вы когда-либо имели дело с библиотекой ATL (Active Template Library — библиотека активных шаблонов) при разработке компонентов СОМ, то знакомы с такой техникой, поскольку в ATL она интенсивно используется, чтобы избежать необходимости вызова виртуальных методов. Та же техника применяется в шаблонах С++ для генерации иерархий во время компиляции.

Давайте рассмотрим прием, который можно применять, чтобы до некоторой степени эмулировать аналогичное поведение. Как это часто бывает, для обеспечения чего-то похожего можно добавить дополнительный промежуточный уровень. В С++, когда шаблонный тип наследуется напрямую от одного из типов-аргументов, часто предполагается, что тип, указанный в аргументе, представляет определенное желательное поведение.

Например, с помощью шаблонов С++ можно сделать следующее:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// ПРИМЕЧАНИЕ: этот код С++ служит только для примера
class Employee
{
public:
long get_salary()  {
return salary;
}
void set_salary( long salary )  {
this->salary = salary;
}
private:
long salary;
};
template< class T > class MyClass : public T {
};
void main () {
MyClass<employee> mylnstance;
mylnstance.get_salary();
}

В функции main обратите внимание на вызов getsalary. Несмотря на то что на первый взгляд он выглядит странно, тем не менее, работает он хорошо, потому что MyClass наследует реализацию типа, переданного в Т во время компиляции.

В данном случае этим типом является Employee, который реализует gets alary, и MyClass наследует эту реализацию. Ясно, что делается предположение, что тип, указанный в Т для MyClass, будет поддерживать метод getsalary. Если это не так, компилятор С++ сообщит об ошибке.

Это — форма статического полиморфизма, или программирования на основе политик. В традиционных случаях полиморфизм, рассматриваемый в контексте виртуальных методов, является динамическим полиморфизмом. Реализовать статический полиморфизм средствами обобщений С# невозможно.

Однако можно потребовать, чтобы аргумент типа, переданный при формировании закрытого типа, поддерживал определенный контракт, используя для этого механизм ограничений (constraints).

Вы можете следить за любыми ответами на эту запись через RSS 2.0 ленту. Вы можете оставить ответ, или trackback с вашего собственного сайта.

Оставьте отзыв

XHTML: Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

 
Rambler's Top100