Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Теоретический_курс.doc
Скачиваний:
37
Добавлен:
10.11.2019
Размер:
7.68 Mб
Скачать

4. Понятие «Разделяемые методы»

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

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

Разделяемые методы особенно полезны для настройки автоматически созданного кода. Они позволяют зарезервировать имя и сигнатуру метода, чтобы автоматически созданный код мог вызвать метод, а разработчик мог сам решить, реализовывать этот метод или нет. Как и разделяемые классы, разделяемые методы позволяют организовать совместную работу автоматически созданного кода и кода, созданного человеком, без дополнительных затрат во время выполнения.

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

// Файл file1.cs

partial void onNameChanged();

// Файл file2.cs

partial void onNameChanged()

{

// Тело метода

}

Некоторые особенности при работе с такими методами:

  • Объявления разделяемого метода должны начинаться с контекстно-зависимого ключевого слова partial, а метод должен возвращать значение типа void.

  • Разделяемые методы могут иметь параметры ref, но не могут иметь параметры out.

  • Разделяемые методы неявно имеют модификатор private и поэтому не могут иметь модификатор virtual.

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

  • Разделяемые методы могут иметь модификаторы static и unsafe.

  • Разделяемые типы могут быть универсальными. Ограничения помещаются в ту часть объявления разделяемого метода, где находится определение, и могут дополнительно повторяться в разделе реализации. Имена параметров и типов параметров необязательно должны совпадать в объявлении реализации и в объявлении определения.

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

3.6.5. Понятие «Структура» Понятие «Структура»

Структура — это фактически объект с «данными», является типом значения и не является классом (класс — это ссылочный тип). Структуры определяются с помощью ключевого слова struct, например:

public struct PostalAddress

{

// Свойства, методы, события, поля (переменные) и прочее...

}

Структуры используют большую часть того же синтаксиса, что и классы, однако они более ограничены по сравнению с последними:

  • В объявлении структуры поля не могут быть инициализированы до тех пор, пока они будут объявлены как постоянные или статические.

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

  • Структуры копируются при присваивании. При присваивании структуры к новой переменной выполняется копирование всех данных, а любое изменение новой копии не влияет на данные в исходной копии. Это важно помнить при работе с коллекциями типов значений, такими как Dictionary<string, myStruct>.

  • Структуры являются типами значений, а классы — ссылочными типами.

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

  • Структуры могут объявлять конструкторы, имеющие параметры.

  • Структура не может быть унаследованной от другой структуры или класса и не может быть основой для других классов. Все структуры наследуют непосредственно от System.ValueType, который наследует от System.Object.

  • Структуры могут реализовывать интерфейсы.

  • Структура может использоваться как тип, допускающий значение NULL, и ей можно назначить значение NULL.

Тип struct подходит для создания несложных объектов, таких как Point, Rectangle и Color. Хотя точку удобно представить в виде класса с автоматически реализуемыми свойствами, в некоторых сценариях структура может оказаться более эффективной. Например, при объявлении массива из 1000 объектов Point потребуется выделить дополнительную память для хранения ссылок на все эти объекты, и структура в таком случае будет более экономичным решением. Поскольку .NET Framework уже содержит объект с именем Point, структура в данном примере называется вместо этого «CoOrds»:

public struct CoOrds

{

public int x, y;

public CoOrds(int p1, int p2)

{

x = p1;

y = p2;

}

}

Определение конструктора по умолчанию (без параметров) для структуры является ошибкой. Ошибкой также является инициализация поля экземпляра в основной части структуры. Можно инициализировать члены структуры с помощью параметризованного конструктора или путем доступа к членам по отдельности после объявления структуры. Любые закрытые или в ином случае недоступные члены можно инициализировать только в конструкторе.

При создании объекта структуры с помощью оператора new объект, создаётся и вызывается соответствующий конструктор. В отличие то классов структуры можно создавать без использования оператора new. В таком случае вызов конструктора отсутствует, что делает выделение более эффективным. Однако поля остаются без значений и объект нельзя использовать до инициализации всех полей.

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

В отличие от классов структуры не поддерживают наследование. Структура не может быть унаследованной от другой структуры или класса и не может быть основой для других классов. Однако структуры наследуют от базового класса Object. Структуры могут реализовывать интерфейсы; этот механизм полностью аналогичен реализации интерфейсов для классов.

Класс нельзя объявить с помощью ключевого слова struct.

Пример использования код структуры «CoOrds». В этом примере демонстрируется инициализация struct с помощью конструктора по умолчанию и с помощью конструктора с параметрами:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace LC_Console

{

public struct CoOrds

{

public int x, y;

public CoOrds(int p1, int p2)

{

x = p1;

y = p2;

}

}

// Инициализируем и декларируем объекты структуры

class TestCoOrds

{

static void Main()

{

// Инициализируем

CoOrds coords1;

coords1.x = 10;

coords1.y = 20;

CoOrds coords2 = new CoOrds(10, 10);

// Выводим результат

Console.Write("CoOrds 1: ");

Console.WriteLine("x = {0}, y = {1}", coords1.x, coords1.y);

Console.Write("CoOrds 2: ");

Console.WriteLine("x = {0}, y = {1}", coords2.x, coords2.y);

// Keep the console window open in debug mode.

Console.WriteLine("Для продолжения нажмите любую клавишу . . .");

Console.ReadKey();

}

}

}

/* Выведет:

* CoOrds 1: x = 10, y = 20

* CoOrds 2: x = 10, y = 10

* Для продолжения нажмите любую клавишу . . .

*/

В коде выше описаны оба случая использования инициализации члена структуры. С new и без.