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

10.2.7Разделяемые методы

Разделяемые методы могут быть определены в одной части объявления типа и реализованы в другой. Реализация является необязательной. Если ни одна из частей не реализует разделяемый метод, объявление разделяемого метода и все вызовы к нему удаляются из объявления типа, полученного путем комбинирования частей.

Разделяемые методы не могут определять модификаторы доступа, но неявно являются private. Типом возвращаемого значения разделяемого метода должен быть void, а параметры не могут иметь модификатора out. Идентификатор partial определяется в качестве специального ключевого слова в объявлении метода, только если он появляется непосредственно перед типом void, в противном случае он может использоваться в качестве обычного идентификатора. Разделяемый метод не может явно реализовывать методы интерфейсов.

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

  • Объявления должны иметь одинаковые модификаторы (необязательно в одинаковом порядке), имя метода, количество параметров типа и количество параметров.

  • Соответствующие параметры в объявлениях должны иметь одинаковые модификаторы (необязательно в одном порядке) и одинаковые типы (отличия по модулю в именах параметров типа).

  • Соответствующие параметры типа в объявлениях должны иметь одинаковые ограничения (отличия по модулю в именах параметров типа).

Реализующее объявление разделяемого метода может содержаться в той же части, что и соответствующее определяющее объявление разделяемого метода.

Только определяющий разделяемый метод участвует в разрешении перегрузки. Таким образом, независимо от наличия реализующего объявления, выражения вызова могут обращаться к вызовам разделяемого метода. Поскольку разделяемый метод всегда возвращает значение void, такие выражения вызова всегда будут являться операторами выражения. Кроме того, так как разделяемый метод является неявно private, такие операторы всегда будут возникать в той части объявления типа, в рамках которой объявлен разделяемый метод.

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

При наличии для заданного разделяемого метода реализующего объявления вызовы разделяемых методов сохраняются. Разделяемый метод инициирует объявление метода аналогично реализующему объявлению разделяемого метода, исключая следующее.

  • Модификатор partial не включается.

  • Атрибутами в результирующем объявлении метода являются скомбинированные атрибуты определяющего и реализующего объявлений разделяемого метода в неопределенном порядке. Дубликаты не удаляются.

  • Атрибутам параметров в результирующем объявлении метода являются скомбинированные атрибуты соответствующих параметров определяющего и реализующего объявлений разделяемого метода в неопределенном порядке. Дубликаты не удаляются.

Если для разделяемого метода M задано определяющее объявление, а реализующее объявление не задано, применяются следующие ограничения.

  • Создание делегата метода является ошибкой времени компилирования (§7.6.10.5).

  • Ссылка на M внутри анонимной функции, преобразованной в тип дерева выражений, является ошибкой времени компилирования (§6.5.2).

  • Выражения, возникающие в качестве части вызова M, не воздействуют на состояние определенного присваивания (§5.3), которое может привести к ошибкам времени компилирования.

  • Метод M не может являться точкой входа приложения (§3.1).

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

partial class Customer { string name;

public string Name {

get { return name; }

set { OnNameChanging(value); name = value; OnNameChanged(); }

}

partial void OnNameChanging(string newName);

partial void OnNameChanged(); }

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

class Customer { string name;

public string Name {

get { return name; }

set { name = value; } } }

Предположим, что задана другая часть, предоставляющая реализующие объявления разделяемых методов:

partial class Customer { partial void OnNameChanging(string newName) { Console.WriteLine(“Changing “ + name + “ to “ + newName); }

partial void OnNameChanged() { Console.WriteLine(“Changed to “ + name); } }

Тогда результирующее объявление скомбинированного класса будет эквивалентно следующему:

class Customer { string name;

public string Name {

get { return name; }

set { OnNameChanging(value); name = value; OnNameChanged(); }

}

void OnNameChanging(string newName) { Console.WriteLine(“Changing “ + name + “ to “ + newName); }

void OnNameChanged() { Console.WriteLine(“Changed to “ + name); } }

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