Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharp Language Specification.doc
Скачиваний:
13
Добавлен:
26.09.2019
Размер:
4.75 Mб
Скачать

10.3.1Тип экземпляра

Каждое объявление класса имеет связанный привязанный тип (§4.4.3), тип экземпляра. Для объявления универсального класса тип экземпляра формируется путем создания сформированного типа (§4.4) на основе объявления типа с каждым предоставленным аргументом типа, являющимся соответствующим параметром типа. Поскольку тип экземпляра использует параметры типа, он может быть использован только в том случае, когда параметры типа находятся в его области, т. е. в рамках объявления класса. Типом экземпляра является this для кода, написанного внутри объявления класса. Для неуниверсальных классов типом экземпляра является просто объявленный класс. Далее представлены объявления класса с их типами экземпляров.

class A<T> // instance type: A<T> { class B {} // instance type: A<T>.B

class C<U> {} // instance type: A<T>.C<U> }

class D {} // instance type: D

10.3.2Члены сформированных типов

Не унаследованные члены сформированного типа получаются путем замещения для каждого параметра_типа в объявлении члена соответствующего аргумента_типа сформированного типа. Процесс замещения основан на семантическом значении объявлений типа и не является простым текстовым замещением.

Например, в объявлении универсального класса

class Gen<T,U> { public T[,] a;

public void G(int i, T t, Gen<U,T> gt) {...}

public U Prop { get {...} set {...} }

public int H(double d) {...} }

сформированный тип Gen<int[],IComparable<string>> имеет следующие члены

public int[,][] a;

public void G(int i, int[] t, Gen<IComparable<string>,int[]> gt) {...}

public IComparable<string> Prop { get {...} set {...} }

public int H(double d) {...}

Типом члена a в объявлении универсального класса Gen является «двумерный массив T», поэтому типом члена a в сформированном выше типе является «двумерный массив одномерного массива int», или int[,][].

В рамках членов функции экземпляра типом this является тип экземпляра (§10.3.1) содержащего объявления.

Все члены универсального класса могут использовать параметры типа из любого включающего класса непосредственно или в качестве части сформированного типа. Когда определенный закрытый сформированный тип (§4.4.2) используется во время выполнения, каждое использование параметра типа заменяется фактическим аргументом типа, предоставляемым сформированному типу. Пример.

class C<V> { public V f1; public C<V> f2 = null;

public C(V x) { this.f1 = x; this.f2 = this; } }

class Application { static void Main() { C<int> x1 = new C<int>(1); Console.WriteLine(x1.f1); // Prints 1

C<double> x2 = new C<double>(3.1415); Console.WriteLine(x2.f1); // Prints 3.1415 } }

10.3.3Наследование

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

  • Наследование транзитивно. Если C произведено из B, а B произведено из A, то C унаследует как члены, объявленные в B, так и члены, объявленные в A.

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

  • Конструкторы экземпляров, деструкторы и статические конструкторы не наследуются, но все другие члены, независимо от их объявленной доступности, наследуются (§3.5). Но в зависимости от их объявленной доступности, унаследованные члены могут быть недоступны в производном классе.

  • Производный класс может скрывать (§3.7.1.2) унаследованные члены путем объявления новых членов с тем же именем или с той же сигнатурой. Обратите внимание, что скрытие унаследованного члена не приводит к удалению данного члена, оно просто приводит к тому, что этот член становится недоступен непосредственно через производный класс.

  • Экземпляр класса содержит набор всех полей экземпляра, объявленных в классе и его базовом классе, и существует неявное преобразование (§6.1.6) из типа производного класса в любой из его типов базового класса. Таким образом, ссылка на экземпляр некоторого производного класса может рассматриваться как ссылка на экземпляр какого-либо из его базовых классов.

  • Класс может объявить виртуальные методы, свойства и индексаторы, а производный класс может переопределить реализацию данных членов функций. Это позволяет классам реализовывать полиморфное поведение, при котором действия, выполняемые вызовом члена функции, отличаются в зависимости от типа времени выполнения экземпляра, в котором вызывается член функции.

Унаследованным членом типа сформированного класса являются члены непосредственного типа базового класса (§10.1.4.1), который обеспечивается путем замещения аргументов типа сформированного типа для каждого вхождения соответствующих параметров типа в спецификации_базового_класса. В свою очередь, данные члены преобразуются путем замещения для каждого параметра_типа в объявлении члена соответствующего аргумента_типа спецификации_базового_класса.

class B<U> { public U F(long index) {...} }

class D<T>: B<T[]> { public T G(string s) {...} }

В предыдущем примере сформированный тип D<int> имеет неунаследованный член public int G(string s), получаемый путем замещения аргумента типа int на параметр типа T. D<int>, который также имеет наследуемый член из объявления класса B. Данный унаследованный член определяется путем определения типа базового класса B<int[]> из D<int> посредством замещения int для T в спецификации базового класса B<T[]>. После этого в качестве аргумента типа B int[] замещается для U в public U F(long index), что приводит к унаследованному члену public int[] F(long index).

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]