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

7.6.2.1Инвариантность значения в блоках

Для каждого вхождения данного идентификатора в качестве простого_имени в выражении или деклараторе внутри области объявления локальных переменных (§3.3), непосредственно включающей это вхождение, каждое вхождение того же самого идентификатора в качестве простого_имени в выражении или декларатора должно ссылаться на одну и ту же сущность. Это правило позволяет гарантировать, что внутри определенного блока, блока switch, а также операторов for, foreach и using имя всегда имеет одинаковое значение.

В примере

class Test { double x;

void F(bool b) { x = 1.0; if (b) { int x; x = 1; } } }

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

class Test { double x;

void F(bool b) { if (b) { x = 1.0; } else { int x; x = 1; } } }

ошибки не возникает, поскольку имя x не используется во внешнем блоке.

Обратите внимание, что правило инвариантности значения применяется только к простым именам. Один идентификатор вполне может иметь одно значение в виде простого имени и другое значение в виде правого операнда в методе доступа к члену (§7.6.4). Например:

struct Point { int x, y;

public Point(int x, int y) { this.x = x; this.y = y; } }

В примере выше демонстрируется общий шаблон использования имен полей в качестве имен параметров в конструкторе экземпляра. В примере простые имена x и y относятся к параметрам, но это не мешает выражениям доступа к членам this.x и this.y иметь доступ к полям.

7.6.3Выражения со скобками

Выражение_со_скобками состоит из выражения, заключенного в скобки.

выражение_в_скобках: ( выражение )

Выражение_со_скобками вычисляется путем вычисления выражения внутри скобок. Если выражение внутри скобок обозначает пространство имен или тип, возникает ошибка времени компиляции. Иначе результатом выражения_со_скобками является результат вычисления содержащегося выражения.

7.6.4Доступ к члену

Доступ_к_члену состоит из первичного_выражения, стандартного_типа или уточненного_члена_псевдонима, за которым следует точка «.» и идентификатор. В конце может находиться список_аргументов_типа.

метод_доступа_к_члену: основное_выражение . идентификатор список аргументов типанеобяз стандартный тип . идентификатор список аргументов типанеобяз уточненный член псевдонима . идентификатор

встроенный тип: один из следующих: bool byte char decimal double float int long object sbyte short string uint ulong ushort

Создание уточненного_члена_псевдонима определяется в разделе §9.7.

Доступ_к_члену имеет вид E.I или одну из форм E.I<A1, ..., AK>, где E — первичное_выражение, I — один идентификатор, а <A1, ..., AK> — необязательный список_аргументов_типа. Если список_аргументов_типа не указан, K считается равным нулю.

Доступ_к_члену с первичным_выражением типа dynamic привязывается динамически (§7.2.2). В этом случае компилятор классифицирует доступ к члену как доступ к свойству типа dynamic. Представленные ниже правила определения значения доступа_к_члену затем применяются во время выполнения, используя тип времени выполнения, а не тип времени компиляции первичного_выражения. Если класс времени выполнения ведет к группе методов, то метод доступа к члену должен являться первичным_выражением для выражения_вызова.

Результат метода_доступа_к_члену вычисляется и классифицируется следующим образом.

  • Если K равно нулю, E является пространством имен и E содержит вложенное пространство имен I, то результатом является это пространство имен.

  • Иначе, если E является пространством имен, E содержит доступный тип с именем I и K параметрами типа, то результатом является этот тип, сформированный с указанными аргументами типа.

  • Если E является стандартным_типом или основным_выражением, которое классифицируется как тип, и если E не является параметром типа и если при поиске члена I (§7.4) в E с K параметрами типа было найдено соответствие, то E.I вычисляется и классифицируется следующим образом.

  • Если I обозначает тип, то результатом является этот тип, сформированный с указанными аргументами типа.

  • Если I обозначает один или несколько методов, то результатом является группа методов без связанного выражения экземпляра. Если указан список аргументов типа, он используется при вызове универсального метода (§7.6.5.1).

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

  • Если I обозначает поле типа static, то

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

  • Иначе результатом является переменная, а именно статическое поле I в E.

  • Если I обозначает событие типа static, то

  • Если внутри класса или структуры, в которой объявляется событие, имеется ссылка и это событие было объявлено без объявлений_метода_доступа_к_событию (§10.8), то E.I обрабатывается точно так же, как если бы I было статическим полем.

  • Иначе результатом является метод доступа к событию без связанного выражения экземпляра.

  • Если I обозначает константу, то результатом является значение, а именно значение этой константы.

  • Если I обозначает член перечисления, то результатом является значение, а именно значение этого члена перечисления.

  • Иначе E.I является недопустимой ссылкой на член, и возникает ошибка времени компиляции.

  • Если E является методом доступа к свойству или индексатору, переменной или значением с типом T и при поиске члена I (§7.4) в T с K аргументами типа было найдено соответствие, то E.I вычисляется и классифицируется следующим образом.

  • Во-первых, если E является свойством или методом доступа к индексатору, то происходит получение значения свойства или метода доступа к индексатору (§7.1.1) и класс E меняется на значение.

  • Если I обозначает один или несколько методов, то результатом является группа методов со связанным выражением экземпляра E. Если указан список аргументов типа, он используется при вызове универсального метода (§7.6.5.1).

  • Если I обозначает свойство экземпляра, то результатом является метод доступа к свойству со связанным выражением экземпляра E.

  • Если T является типом_класса и I обозначает поле экземпляра этого типа_класса, то

  • Если значение E равно null, то вызывается исключение System.NullReferenceException.

  • Иначе, если поле предназначено только для чтения и вне статического конструктора класса или структуры, в которой объявляется поле, имеется ссылка, то результатом является значение, а именно значение поля I в объекте, на который ссылается E.

  • Иначе результатом является переменная, а именно поле I в объекте, на который ссылается E.

  • Если T является типом_структуры и I обозначает поле экземпляра этого типа_структуры, то

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

  • Иначе результатом является переменная, а именно поле I в экземпляре структуры, предоставленном E.

  • Если I обозначает событие экземпляра, то

  • Если внутри класса или структуры, в которой объявляется событие, имеется ссылка и это событие было объявлено без объявлений_метода_доступа_к_событию (§10.8), то E.I обрабатывается точно так же, как если бы I было полем экземпляра.

  • Иначе результатом является метод доступа к событию со связанным выражением экземпляра E.

  • Иначе выполняется попытка обработать E.I как вызов метода расширения (§7.6.5.2). Если такой вызов завершается сбоем, E.I является недопустимой ссылкой на член и возникает ошибка времени привязки.

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