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; Console.WriteLine("Переменная val теперь содержит: " + val + '\n'); string str2 = str.ToLower(CultureInfo.CurrentCulture); Console.WriteLine("Переменная str2 содержит: " + str2); // Поддерживаются неявные преобразования из динамических типов. int х = val * 2; Console.WriteLine("Переменная x содержит: " + х); }
} Выполнение этой программы дает следующий результат.
Переменная str содержит: Это строка Переменная val содержит: 10
Переменная str теперь содержит: ЭТО СТРОКА Переменная val теперь содержит: 12
Переменная str2 содержит: это строка Переменная х содержит: 24 Обратите внимание в этой программе на две переменные str и val, объявляемые с помощью типа dynamic. Это означает, что проверка на соответствие типов операций с участием обеих переменных не будет произведена во время компиляции. В итоге для них оказывается пригодной любая операция. В данном случае для переменной str вызываются методы ToUpper и ToLower класса String, а переменная уча ствует в операциях сложения и умножения. И хотя все перечисленные выше действия совместимы с типами объектов, присваиваемых обеим переменным в рассматривае мом здесь примере, компилятору об этом ничего не известно — он просто принимает. И это, конечно, упрощает программирование динамических процедур, хотя и допу скает возможность появления ошибок в подобных действиях во время выполнения. В разбираемом здесь примере программа ведет себя "правильно" во время выпол нения, поскольку объекты, присваиваемые упомянутым выше переменным, поддер живают действия, выполняемые в программе. В частности, переменной val присваи вается целое значение, и поэтому она поддерживает такие целочисленные операции, как сложение. А переменной str присваивается символьная строка, и поэтому она поддерживает строковые операции. Следует, однако, иметь в виду, что ответственность за фактическую поддержку типом объекта, на который делается ссылка, всех операций над данными типа dynamic возлагается на самого программирующего. В противном случае выполнение программы завершится аварийным сбоем. В приведенном выше примере обращает на себя внимание еще одно обстоятель ство: переменной типа dynamic может быть присвоен любой тип ссылки на объект благодаря неявному преобразованию любого типа в тип dynamic. Кроме того, тип dynamic автоматически преобразуется в любой другой тип. Разумеется, если во время выполнения такое преобразование окажется неправильным, то произойдет ошибка при выполнении. Так, если добавить в конце рассматриваемой здесь программы сле дующую строку кода: