23.1 Неполные описания
Новый модификатор типа, partial, используется при определении типа в
нескольких частях. Чтобы гарантировать совместимость с существующими
программами, этот модификатор отличается от других: как и get и
set, он не является ключевым словом и должен стоять непосредственно
перед одним из ключевых слов class, struct или
interface.
class-declaration:
attributesopt class-modifiersopt partialopt
class identifier type-parameter-listopt
class-baseopt type-parameter-constraints-clausesopt
class-body ;opt
struct-declaration:
attributesopt struct-modifiersopt partialopt struct
identifier type-parameter-listopt struct-interfacesopt
type-parameter-constraints-clausesopt struct-body ;opt
interface-declaration:
attributesopt interface-modifiersopt partialopt interface
identifier type-parameter-listopt interface-baseopt
type-parameter-constraints-clausesopt interface-body ;opt
Каждая часть описания неполного типа должна включать модификатор
partial и должна быть объявлена в том же пространстве имен, что и
другие части. Модификатор partial свидетельствует о том, что где-то
могут существовать дополнительные части описания типа, но существование таких
дополнительных частей не является необходимым условием; включать модификатор
partial для одиночного описания типа не является ошибкой.
Все части неполного типа должны быть скомпилированы вместе из условия, чтобы
эти части могли быть объединены во время компиляции. В частности, неполные типы
не позволяют расширение уже откомпилированных типов.
Вложенные типы с помощью модификатора partial также могут быть
объявлены в нескольких частях. Обычно включающий тип также объявляется
partial, и каждая часть вложенного типа объявляется в разных частях
включающего его типа.
Не разрешается использование модификатора partial для описаний
делегатов или перечислений.
23.1.1 Атрибуты
Атрибуты неполного типа определяются путем комбинации в неустановленном
порядке атрибутов каждой из частей. Если атрибут размещается в нескольких
частях, это эквивалентно многократному определению атрибута в типе. Например,
две части:
[Attr1, Attr2("hello")]
partial class A {}
[Attr3, Attr2("goodbye")]
partial class A {}
эквивалентны такому описанию:
[Attr1, Attr2("hello"), Attr3, Attr2("goodbye")]
class A {}
Атрибуты параметров типа комбинируются аналогичным образом.
23.1.2 Модификаторы
Когда описание неполного типа включает и модификатор доступа
(public, protected, internal или private),
он должен согласовываться со всеми другими частями, которые включают
модификаторы доступа. Если ни одна из частей неполного типа не включает
модификаторы доступа, типу присваивается стандартный модификатор (§3.5.1).
Когда одно или более из неполных описаний вложенного типа включает
модификатор new, в случае, если вложенный тип скрывает унаследованный
член (§3.7.1.2), предупреждение не выдается.
Если одно или более из неполных описаний класса включают модификатор
abstract, класс считается абстрактным (§10.1.1.1). В противном случае,
класс считается неабстрактным.
Если одно или более из неполных описаний класса включают модификатор
sealed, класс считается sealed (§10.1.1.2). В противном случае, класс
считается не sealed.
Обратите внимание, что класс не может быть одновременно абстрактным и
sealed.
Когда в описании неполного типа используется модификатор unsafe,
только эта конкретная часть считается небезопасным контекстом (§18.1).
23.1.3 Параметры типов и ограничения
Если шаблонный тип объявлен в нескольких частях, параметры типа должны
указываться в каждой части. Каждая часть должна иметь одинаковое количество
параметров типа, и имена и порядок параметров типа должны быть одинаковыми.
Когда описание неполного шаблонного типа включает ограничения параметров типа
(операторы where), ограничения должны согласовываться со всеми другими
частями, которые включают ограничения. В частности, каждая часть, которая
включает ограничения, должна иметь ограничения для того же набора параметров
типа, и для каждого параметра типа набор ограничений класса, интерфейса и
конструктора должен быть одинаковым. Если ни одна часть неполного шаблонного
типа не определяет ограничений параметров типа, параметры типа считаются
неограниченными.
Пример
partial class Dictionary<K,V>
where K: IComparable<K>
where V: IKeyProvider<K>, IPersistable
{
...
}
partial class Dictionary<K,V>
where V: IPersistable, IKeyProvider<K>
where K: IComparable<K>
{
...
}
partial class Dictionary<K,V>
{
...
}
верен, потому что те части, которые включают ограничения (первые две)
определяют тот же набор ограничений класса, интерфейса, конструктора для того же
набора параметров типа, соответственно.
23.1.4 Базовый класс
Когда описание неполного класса включает определение базового класса, оно
должно согласовываться со всеми другими частями, которые включают определение
базового класса. Если ни одна из частей неполного класса не включает определение
базового класса, им становится System.Object (§10.1.2.1).
23.1.5 Базовый интерфейс
Набором базовых интерфейсов для типа, объявленного в нескольких частях,
является объединение базовых интерфейсов, определенных в каждой части.
Конкретный базовый интерфейс может упоминаться только один раз в каждой части,
но несколько частей могут называть один и тот же базовый интерфейс(-ы). Должна
быть только одна реализация членов любого данного базового интерфейса.
В примере
partial class C: IA, IB {...}
partial class C: IC {...}
partial class C: IA, IB {...}
набор базовых интерфейсов для класса C — IA, IB и
IC.
Обычно каждая часть предоставляет реализацию интерфейса(-сов), объявленных в
этой части; однако это необязательное требование. Часть может предоставлять
реализацию для интерфейса, объявленного в другой части:
partial class X
{
int IComparable.CompareTo(object o) {...}
}
partial class X: IComparable
{
...
}
23.1.6 Члены
Члены объявленного в нескольких частях типа — это просто объединение членов,
объявленных в каждой части. Тела всех частей описания типа используют совместно
одно пространство описания (§3.3), и область видимости каждого члена (§3.7)
распространяется на тела всех частей. Область доступности любого члена всегда
включает все части типа, в который он входит; private член, объявленный
в одной части, свободно доступен из другой части. Если один и тот же член
объявлен в нескольких частях типа, возникает ошибка компиляции, если только этот
член не является типом с модификатором partial.
partial class A
{
int x; // Ошибка, нельзя объявлять x более, чем один раз
partial class Inner // Ok, Inner – неполный тип
{
int y;
}
}
partial class A
{
int x; // Ошибка, нельзя объявлять x более, чем один раз
partial class Inner // Ok, Inner – неполный тип
{
int z;
}
}
Хотя порядок расположения членов не имеет значения для C#-кода, он может быть
важен при сопряжении с другими языками и средами. В этих случаях порядок
расположения членов в типе, объявленном в нескольких частях, не
определен.
23.2 Связывание имен
Хотя каждая часть расширяемого типа должна быть объявлена в одном и том же
пространстве имен, части обычно создаются в описаниях разных пространств имен.
Таким образом, для каждой части могут существовать различные директивы
using (§9.3). При интерпретации простых имен (§7.5.2) в рамках одной
части, учитываются директивы using только того описания(-ий)
пространства имен, которое включает в себя эту часть. В результате этого могут
возникнуть одинаковые идентификаторы, имеющие разные значения в разных
частях:
namespace N
{
using List = System.Collections.ArrayList;
partial class A
{
List x; // x имеет тип System.Collections.ArrayList
}
}
namespace N
{
using List = Widgets.LinkedList;
partial class A
{
List y; // y имеет тип Widgets.LinkedList
}
}
Никакая часть настоящей статьи не может быть воспроизведена или
передана в какой бы то ни было форме и какими бы то ни было средствами, будь то
электронные или механические, если на то нет письменного разрешения владельцев
авторских прав.
Материал, изложенный в данной статье, многократно
проверен. Но, поскольку вероятность технических ошибок все равно существует,
сообщество не может гарантировать абсолютную точность и правильность приводимых
сведений. В связи с этим сообщество не несет ответственности за возможные
ошибки, связанные с использованием статьи.