dynamic 型の使用 (C# プログラミング ガイド)Using type dynamic (C# Programming Guide)

C# 4C# 4 では、dynamic という新しい型が導入されています。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. したがって、オブジェクトが COM API、IronPython などの動的言語、HTML ドキュメント オブジェクト モデル (DOM)、リフレクション、プログラムの他の場所のいずれから値を取得するのかを考慮する必要はありません。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 インスタンス メソッドにパラメーターが 1 つしかない場合、ec.exampleMethod1(10, 4) メソッドへの最初の呼び出しは引数を 2 つ含むため、コンパイラはこの呼び出しを無効と認識します。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) メソッドの 2 番目の呼び出しは、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 の型は、dynamic ではなく、ExampleClass です。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;

dynamic 型の引数を使用したオーバーロードの解決Overload resolution with arguments of type dynamic

メソッド呼び出しの 1 つ以上の引数が 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);

動的言語ランタイムDynamic language runtime

動的言語ランタイム (DLR) は、.NET Framework 4.NET Framework 4 の新しい API です。The dynamic language runtime (DLR) is a new API in .NET Framework 4.NET Framework 4. DLR は、C# の dynamic 型だけでなく、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 の詳細については、「動的言語ランタイムの概要」を参照してください。For more information about the DLR, see Dynamic Language Runtime Overview.

COM 相互運用COM interop

C# 4C# 4 には、Office オートメーション API などの COM API との相互運用エクスペリエンスを強化する複数の機能があります。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 型が導入されて COM シグネチャの object のオカレンスを 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];
TitleTitle 説明Description
dynamicdynamic dynamic キーワードの使用法について説明します。Describes the usage of the dynamic keyword.
動的言語ランタイムの概要Dynamic Language Runtime Overview DLR の概要について説明します。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.
方法: Visual C# の機能を使用して Office 相互運用オブジェクトにアクセスするHow to: Access Office Interop Objects by Using Visual 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.