Ниже приведена расширенная версия предыдущей программы, в которой создается частичный метод Show()
. Этот метод вызывается другим методом, ShowXY()
. Ради удобства все части класса XY
представлены в одном файле, но они могут быть распределены по отдельным файлам, как было показано в предыдущем разделе.
// Продемонстрировать применение частичного метода.
using System;
partial class XY {
public XY(int a, int b) {
X = a;
Y = b;
}
// Объявить частичный метод,
partial void Show();
}
partial class XY {
public int X { get; set; }
// Реализовать частичный метод,
partial void Show() {
Console.WriteLine("{0}, {1}", X, Y);
}
}
partial class XY {
public int Y { get; set; }
// Вызвать частичный метод,
public void ShowXY() {
Show();
}
}
class Test {
static void Main() {
XY xy = new XY(1, 2);
xy.ShowXY();
}
}
Обратите внимание на то, что метод Show()
объявляется в одной части класса XY
, а реализуется в другой его части. В реализации этого метода выводятся значения координат X и Y. Это означает, что когда метод Show()
вызывается из метода ShowXY()
, то данный вызов действительно имеет конкретные последствия: вывод значений координат X и Y. Но если закомментировать реализацию метода Show()
, то его вызов из метода ShowXY()
ни к чему не приведет.
Частичным методам присущ ряд следующих ограничений. Они должны возвращать значение типа void
. У них не может быть модификаторов доступа и они не могут быть виртуальными. В них нельзя также использовать параметры out
.
Создание объектов динамического типа
Как уже упоминалось не раз, начиная с главы 3, C# является строго типизированным языком программирования. Вообще говоря, это означает, что все операции проверяются во время компиляции на соответствие типов, и поэтому действия, не поддерживаемые конкретным типом, не подлежат компиляции. И хотя строгий контроль типов дает немало преимуществ программирующему, помогая создавать устойчивые и надежные программы, он может вызвать определенные осложнения в тех случаях, когда тип объекта остается неизвестным вплоть до времени выполнения. Нечто подобное может произойти при использовании рефлексии, доступе к COM-объекту или же в том случае, если требуется возможность взаимодействия с таким динамическим языком, как, например, IronPython
. До появления версии C# 4.0 подобные ситуации были трудноразрешимы. Поэтому для выхода из столь затруднительного положения в версии C# 4.0 был внедрен новый тип данных под названием dynamic
.
За одним важным исключением, тип dynamic
очень похож на тип object
, поскольку его можно использовать для ссылки на объект любого типа. А отличается он от типа object
тем, что вся проверка объектов типа dynamic
на соответствие типов откладывает до времени выполнения, тогда как объекты типа object подлежат этой проверке во время компиляции. Преимущество откладывания подобной проверки до времени выполнения состоит в том, что во время компиляции предполагается, что объект типа dynamic
поддерживает любые операции, включая применение операторов, вызовы методов, доступ к полям и т.д. Это дает возможность скомпилировать код без ошибок. Конечно, если во время выполнения фактический тип, присваиваемый объекту, не поддерживает ту или иную операцию, то возникнет исключительная ситуация во время выполнения.
В приведенном ниже примере программы применение типа dynamic демонстрируется на практике.
// Продемонстрировать применение типа dynamic,
using System;
using System.Globalization;
class DynDemo {
static void Main() {
// Объявить две динамические переменные,
dynamic str;
dynamic val;
// Поддерживается неявное преобразование в динамические типы.
// Поэтому следующие присваивания вполне допустимы,
str = "Это строка";
val = 10;
Console.WriteLine("Переменная str содержит: " + str);
Console.WriteLine("Переменная val содержит: " + val + '\n');
str = str.ToUpper(CultureInfo.CurrentCulture);
Console.WriteLine("Переменная str теперь содержит: " + str);
val = val + 2;