Использование типа dynamic (руководство по программированию на C#)Using type dynamic (C# Programming Guide)

C# 4 добавляет новый тип dynamic.C# 4 introduces a new type, dynamic. Этот тип является статическим, но объект типа dynamic обходит проверку статического типа.The type is a static type, but an object of type dynamic bypasses static type checking. В большинстве случаев он работает как тип object.In most cases, it functions like it has type object. Во время компиляции предполагается, что элемент, типизированный как dynamic, поддерживает любые операции.At compile time, an element that is typed as dynamic is assumed to support any operation. Это значит, что вам не придется задумываться о том, получает ли объект значение из API COM, из динамического языка, такого как IronPython, из модели DOM HTML, из отражения или из другой части программы.Therefore, you do not have to be concerned about whether the object gets its value from a COM API, from a dynamic language such as IronPython, from the HTML Document Object Model (DOM), from reflection, or from somewhere else in the program. При этом если код недопустимый, ошибки перехватываются во время выполнения.However, if the code is not valid, errors are caught at run time.

Например, если метод экземпляра exampleMethod1 в следующем коде имеет только один параметр, компилятор определяет, что первый вызов метода ec.exampleMethod1(10, 4) недопустим, поскольку содержит два аргумента.For example, if instance method exampleMethod1 in the following code has only one parameter, the compiler recognizes that the first call to the method, ec.exampleMethod1(10, 4), is not valid because it contains two arguments. Этот вызов приводит к ошибке компилятора.The call causes a compiler error. Второй вызов метода dynamic_ec.exampleMethod1(10, 4) компилятором не проверяется, поскольку dynamic_ec имеет тип dynamic.The second call to the method, dynamic_ec.exampleMethod1(10, 4), is not checked by the compiler because the type of dynamic_ec is dynamic. В результате ошибка компилятора не возникает.Therefore, no compiler error is reported. Тем не менее ошибка не может оставаться незамеченной неограниченное время.However, the error does not escape notice indefinitely. Она перехватывается во время выполнения и вызывает исключение времени выполнения.It is caught at run time and causes a run-time exception.

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.The role of the compiler in these examples is to package together information about what each statement is proposing to do to the object or expression that is typed as dynamic. Во время выполнения сохраненная информация проверяется, а все недействительные операторы вызывают исключение времени выполнения.At run time, the stored information is examined, and any statement that is not valid causes a run-time exception.

Результатом большинства динамических операций является сам dynamic.The result of most dynamic operations is itself dynamic. Например, при наведении указателя мыши на testSum в следующем примере IntelliSense отображает тип (локальная переменная) dynamic testSum.For example, if you rest the mouse pointer over the use of testSum in the following example, IntelliSense displays the type (local variable) dynamic testSum.

dynamic d = 1;
var testSum = d + 3;
// Rest the mouse pointer over testSum in the following statement.
System.Console.WriteLine(testSum);

Операции, в которых результатом не является dynamic:Operations in which the result is not dynamic include:

  • Преобразования из dynamic в другой тип.Conversions from dynamic to another type.
  • Вызовы конструктора, которые включают аргументы типа dynamic.Constructor calls that include arguments of type dynamic.

Например, testInstance в следующих объявлениях имеет тип ExampleClass, а не dynamic:For example, the type of testInstance in the following declaration is ExampleClass, not dynamic:

var testInstance = new ExampleClass(d);

Примеры преобразований приводятся в следующем разделе — "Преобразования".Conversion examples are shown in the following section, "Conversions."

ПреобразованияConversions

Преобразования динамических объектов в другие типы выполнять очень просто.Conversions between dynamic objects and other types are easy. Это позволяет разработчику переключаться между динамическим и нединамическим поведением.This enables the developer to switch between dynamic and non-dynamic behavior.

Любой объект можно преобразовать в динамический тип неявно, как показано в следующих примерах.Any object can be converted to dynamic type implicitly, as shown in the following examples.

dynamic d1 = 7;
dynamic d2 = "a string";
dynamic d3 = System.DateTime.Today;
dynamic d4 = System.Diagnostics.Process.GetProcesses();

И наоборот, явное преобразование можно динамически применить к любому выражению типа dynamic.Conversely, an implicit conversion can be dynamically applied to any expression of type dynamic.

int i = d1;
string str = d2;
DateTime dt = d3;
System.Diagnostics.Process[] procs = d4;

Разрешение перегрузки с аргументами типа dynamicOverload resolution with arguments of type dynamic

Разрешение перегрузки возникают во время выполнения, а не компиляции, если один или несколько аргументов в вызове метода имеют тип dynamic либо получатель вызова метода имеет тип dynamic.Overload resolution occurs at run time instead of at compile time if one or more of the arguments in a method call have the type dynamic, or if the receiver of the method call is of type dynamic. В следующем примере, если единственный доступный метод exampleMethod2 определен как принимающий аргумент строки, отправка d1 как аргумента не вызывает ошибку компилятора, но создает исключение времени выполнения.In the following example, if the only accessible exampleMethod2 method is defined to take a string argument, sending d1 as the argument does not cause a compiler error, but it does cause a run-time exception. Разрешение перегрузки завершается ошибкой во время выполнения, поскольку d1 имеет тип времени выполнения int, а exampleMethod2 требуется строка.Overload resolution fails at run time because the run-time type of d1 is int, and exampleMethod2 requires a string.

// 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);

Среда DLRDynamic language runtime

Среда выполнения динамического языка (DLR) — это новый API в .NET Framework 4.The dynamic language runtime (DLR) is a new API in .NET Framework 4. Она предоставляет инфраструктуру, которая поддерживает тип dynamic в C#, а также реализацию динамических языков программирования, таких как IronPython и IronRuby.It provides the infrastructure that supports the dynamic type in C#, and also the implementation of dynamic programming languages such as IronPython and IronRuby. Дополнительные сведения о DLR см. в разделе Общие сведения о среде DLR.For more information about the DLR, see Dynamic Language Runtime Overview.

взаимодействие COMCOM interop

C# 4 включает несколько функций, улучшающих взаимодействие с интерфейсами API COM, такими как API автоматизации Office.C# 4 includes several features that improve the experience of interoperating with COM APIs such as the Office Automation APIs. К таким усовершенствованиям относятся применение типа dynamic и именованных и необязательных аргументов.Among the improvements are the use of the dynamic type, and of named and optional arguments.

Многие методы COM допускают вариативность в типах аргументов и возвращают тип, назначая типы как object.Many COM methods allow for variation in argument types and return type by designating the types as object. В связи с этим для согласования со строго типизированными переменными в C# необходимо явно приводить значения.This has necessitated explicit casting of the values to coordinate with strongly typed variables in C#. При компиляции с использованием параметра -link (параметры компилятора C#) введение типа dynamic позволяет обрабатывать вхождения object в сигнатурах COM, как если бы они имели тип dynamic, и таким образом избежать большей части приведения.If you compile by using the -link (C# Compiler Options) option, the introduction of the dynamic type enables you to treat the occurrences of object in COM signatures as if they were of type dynamic, and thereby to avoid much of the casting. Например, следующие инструкции показывают, как получить доступ к ячейке в электронной таблице Microsoft Office Excel с типом dynamic и без типа dynamic.For example, the following statements contrast how you access a cell in a Microsoft Office Excel spreadsheet with the dynamic type and without the dynamic type.

// Before the introduction of dynamic.
((Excel.Range)excelApp.Cells[1, 1]).Value2 = "Name";
Excel.Range range2008 = (Excel.Range)excelApp.Cells[1, 1];
// After the introduction of dynamic, the access to the Value property and
// the conversion to Excel.Range are handled by the run-time COM binder.
excelApp.Cells[1, 1].Value = "Name";
Excel.Range range2010 = excelApp.Cells[1, 1];
НазваниеTitle Описание:Description
dynamicdynamic Описывает применение ключевого слова dynamic.Describes the usage of the dynamic keyword.
Общие сведения о среде DLRDynamic Language Runtime Overview Содержит общие сведения о среде DLR — среде выполнения, которая добавляет в общую среду языковой среды исполнения (CLR) набор служб для динамических языков.Provides an overview of the DLR, which is a runtime environment that adds a set of services for dynamic languages to the common language runtime (CLR).
Пошаговое руководство. Создание и использование динамических объектовWalkthrough: Creating and Using Dynamic Objects Содержит пошаговые инструкции по созданию пользовательских динамических объектов и проекта, который обращается к библиотеке IronPython.Provides step-by-step instructions for creating a custom dynamic object and for creating a project that accesses an IronPython library.
Практическое руководство. Доступ к объектам взаимодействия Office с помощью функций языка C#How to access Office interop objects by using C# features Содержит сведения о создании проекта с использованием именованных и необязательных аргументов, типа dynamic и других усовершенствований, которые упрощают доступ к объектам Office API.Demonstrates how to create a project that uses named and optional arguments, the dynamic type, and other enhancements that simplify access to Office API objects.