Использование динамического типа
Тип dynamic
является статическим типом, но объект типа dynamic
проходит проверку статического типа. В большинстве случаев он работает как тип object
. Компилятор предполагает, что dynamic
элемент поддерживает любую операцию. Поэтому не нужно определить, получает ли объект значение из COM-API из динамического языка, например IronPython, из модели объектов HTML-документа (DOM), из отражения или из другого места в программе. Однако если код недействителен, возникают ошибки во время выполнения.
Например, если метод exampleMethod1
экземпляра в следующем коде имеет только один параметр, компилятор распознает, что первый вызов метода недействителен, ec.exampleMethod1(10, 4)
так как он содержит два аргумента. Этот вызов приводит к ошибке компилятора. Компилятор не проверяет второй вызов метода, dynamic_ec.exampleMethod1(10, 4)
так как тип dynamic_ec
имеет значение dynamic
. В результате ошибка компилятора не возникает. Однако ошибка не выходит заметок на неопределенный срок. Он отображается во время выполнения и вызывает исключение во время выполнения.
static void Main(string[] args)
{
ExampleClass ec = new ExampleClass();
// The following call to exampleMethod1 causes a compiler error
// if exampleMethod1 has only one parameter. Uncomment the line
// to see the error.
//ec.exampleMethod1(10, 4);
dynamic dynamic_ec = new ExampleClass();
// The following line is not identified as an error by the
// compiler, but it causes a run-time exception.
dynamic_ec.exampleMethod1(10, 4);
// The following calls also do not cause compiler errors, whether
// appropriate methods exist or not.
dynamic_ec.someMethod("some argument", 7, null);
dynamic_ec.nonexistentMethod();
}
class ExampleClass
{
public ExampleClass() { }
public ExampleClass(int v) { }
public void exampleMethod1(int i) { }
public void exampleMethod2(string str) { }
}
Роль компилятора в этих примерах заключается в том, чтобы упаковать сведения о том, что каждая инструкция предлагает сделать для dynamic
объекта или выражения. Среда выполнения проверяет хранимую информацию и любую инструкцию, которая не является допустимой, вызывает исключение во время выполнения.
Результатом большинства динамических операций является сам dynamic
. Например, при наведении указателя мыши на testSum
в следующем примере IntelliSense отображает тип (локальная переменная) dynamic testSum.
dynamic d = 1;
var testSum = d + 3;
// Rest the mouse pointer over testSum in the following statement.
System.Console.WriteLine(testSum);
Операции, в которых результат не dynamic
включается:
- Преобразования из
dynamic
в другой тип. - Вызовы конструктора, которые включают аргументы типа
dynamic
.
Например, testInstance
в следующих объявлениях имеет тип ExampleClass
, а не dynamic
:
var testInstance = new ExampleClass(d);
Преобразования
Преобразования динамических объектов в другие типы выполнять очень просто. Преобразования позволяют разработчику переключаться между динамическим и нединамических поведением.
Вы можете преобразовать любой объект dynamic
в неявно, как показано в следующих примерах.
dynamic d1 = 7;
dynamic d2 = "a string";
dynamic d3 = System.DateTime.Today;
dynamic d4 = System.Diagnostics.Process.GetProcesses();
И наоборот, можно динамически применять любое неявное преобразование к любому выражению типа dynamic
.
int i = d1;
string str = d2;
DateTime dt = d3;
System.Diagnostics.Process[] procs = d4;
Разрешение перегрузки с аргументами типа dynamic
Разрешение перегрузки возникают во время выполнения, а не компиляции, если один или несколько аргументов в вызове метода имеют тип dynamic
либо получатель вызова метода имеет тип dynamic
. В следующем примере, если единственный доступный exampleMethod2
метод принимает строковый аргумент, отправка d1
как аргумент не приводит к ошибке компилятора, но вызывает исключение во время выполнения. Разрешение перегрузки завершается ошибкой во время выполнения, поскольку d1
имеет тип времени выполнения int
, а exampleMethod2
требуется строка.
// Valid.
ec.exampleMethod2("a string");
// The following statement does not cause a compiler error, even though ec is not
// dynamic. A run-time exception is raised because the run-time type of d1 is int.
ec.exampleMethod2(d1);
// The following statement does cause a compiler error.
//ec.exampleMethod2(7);
Среда DLR
Среда выполнения динамического языка (DLR) предоставляет инфраструктуру, которая поддерживает dynamic
тип в C#, а также реализацию динамических языков программирования, таких как IronPython и IronRuby. Дополнительные сведения о DLR см. в разделе Общие сведения о среде DLR.
взаимодействие COM
Многие методы COM допускают вариативность в типах аргументов и возвращают тип, назначая типы как object
. Взаимодействие COM требует явного приведения значений для координации с строго типизированными переменными в C#. При компиляции с использованием параметра EmbedInteropTypes (параметры компилятора C#) введение типа dynamic
позволяет обрабатывать вхождения object
в сигнатурах COM, как если бы они имели тип dynamic
, и таким образом избежать большей части приведения. Дополнительные сведения об использовании dynamic
типа с COM-объектами см. в статье о доступе к объектам взаимодействия Office с помощью функций C#.
Связанные статьи
Заголовок | Description |
---|---|
Динамический | Описывает применение ключевого слова dynamic . |
Общие сведения о среде DLR | Содержит общие сведения о среде DLR — среде выполнения, которая добавляет в общую среду языковой среды исполнения (CLR) набор служб для динамических языков. |
Пошаговое руководство. Создание и использование динамических объектов | Содержит пошаговые инструкции по созданию пользовательских динамических объектов и проекта, который обращается к библиотеке IronPython . |