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

7.17.1Простое присваивание

Оператор = называется простым оператором присваивания.

Если левый операнд выражения простого присваивания имеет форму E.P или E[Ei], где E имеет динамический тип во время компиляции, то операция присваивания динамически привязывается (§7.2.2). В этом случае тип времени компиляции выражения присваивания динамический, а разрешение, приведенное ниже, будет иметь место во время выполнения на основе типа E времени выполнения.

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

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

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

Во время выполнения обработка простого присваивания вида x = y включает следующие этапы.

  • Если x классифицируется как переменная, то:

  • x вычисляется для создания переменной.

  • Вычисляется y и при необходимости преобразуется в тип x с помощью неявного преобразования (§6.1).

  • Если переменная, представленная x, является элементом массива ссылочного_типа, то во время выполнения проводится проверка с целью убедиться, что значение, вычисленное для y совместимо с экземпляром массива, элементом которого является x. Проверка оказывается успешной, если y равно null или если существует неявное преобразование значения ссылочного типа (§6.1.6) из фактического типа экземпляра, на который ссылается y, в фактический тип элемента экземпляра массива, содержащего x. В противном случае возникает исключение System.ArrayTypeMismatchException.

  • Значение, получающееся после вычисления и преобразования y, сохраняется в расположении, которое задается значением x.

  • Если x классифицируется как свойство или доступ к индексатору, то:

  • Вычисляются выражение экземпляра (если x не имеет тип static) и список аргументов (если x является доступом к экземпляру), связанные с x, и полученные результаты используются при последующем вызове метода доступа set.

  • Вычисляется y и при необходимости преобразуется в тип x с помощью неявного преобразования (§6.1).

  • Вызывается метод доступа set для x со значением, вычисленным для y, в качестве своего аргумента value.

По правилам ковариации массива (§12.5) значение массива типа A[] может быть ссылкой на экземпляр массива типа B[], если существует неявное преобразование ссылочного типа из B в A. В соответствии с этими правилами присваивание элементу массива ссылочного_типа требует проведения во время выполнения проверки с целью убедиться, что присваиваемое значение совместимо с экземпляром массива. В примере

string[] sa = new string[10]; object[] oa = sa;

oa[0] = null; // Ok oa[1] = "Hello"; // Ok oa[2] = new ArrayList(); // ArrayTypeMismatchException

последнее присваивание вызывает исключение System.ArrayTypeMismatchException, потому что экземпляр ArrayList нельзя сохранить в элементе типа string[].

Когда назначением присваивания является свойство или индексатор типа_структуры, выражение экземпляра, связанное со свойством или доступом к индексатору, должно классифицироваться как переменная. Если выражение экземпляра классифицировано как значение, возникнет ошибка времени привязки. В силу §7.6.4 такое же правило применяется к полям.

При наличии объявлений:

struct Point { int x, y;

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

public int X { get { return x; } set { x = value; } }

public int Y { get { return y; } set { y = value; } } }

struct Rectangle { Point a, b;

public Rectangle(Point a, Point b) { this.a = a; this.b = b; }

public Point A { get { return a; } set { a = value; } }

public Point B { get { return b; } set { b = value; } } }

в примере

Point p = new Point(); p.X = 100; p.Y = 100; Rectangle r = new Rectangle(); r.A = new Point(10, 10); r.B = p;

присваивания для p.X, p.Y, r.A и r.B будут допустимы, потому что p и r являются переменными. Однако в примере

Rectangle r = new Rectangle(); r.A.X = 10; r.A.Y = 10; r.B.X = 100; r.B.Y = 100;

присваивания будут недопустимы, поскольку r.A и r.B не являются переменными.

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