dynamic 型の使用

dynamic 型は静的な型ですが、dynamic 型のオブジェクトは静的な型チェックをバイパスします。 ほとんどの場合、object 型を使用する場合と同様に機能します。 コンパイラは、dynamic 要素がすべての操作をサポートしていることを前提としています。 したがって、オブジェクトが COM API、IronPython などの動的言語、HTML ドキュメント オブジェクト モデル (DOM)、リフレクション、プログラムの他の場所のいずれから値を取得するのかを決定する必要はありません。 ただし、コードが無効な場合には、実行時にエラーが発生します。

たとえば、次のコードの exampleMethod1 インスタンス メソッドにパラメーターが 1 つしかない場合、ec.exampleMethod1(10, 4) メソッドへの最初の呼び出しは引数を 2 つ含むため、コンパイラはこの呼び出しを無効と認識します。 この呼び出しではコンパイラ エラーが発生します。 dynamic_ec.exampleMethod1(10, 4) メソッドの 2 番目の呼び出しは、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 の型は、dynamic ではなく、ExampleClass です。

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 型の引数を使用したオーバーロードの解決

メソッド呼び出しの 1 つ以上の引数が 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) は、C# での dynamic 型と、IronPython や IronRuby などの動的プログラミング言語の実装を提供します。 DLR の詳細については、「動的言語ランタイムの概要」を参照してください。

COM 相互運用

多くの COM メソッドでは、型を object と指定することによって、引数の型と戻り値の型にバリエーションを持たせることができます。 COM 相互運用では、C# での厳密に型指定された変数との連携に値の明示的なキャストが必要です。 EmbedInteropTypes (C# コンパイラ オプション) オプションを使用してコンパイルする場合、dynamic 型が導入されて COM シグネチャの object のオカレンスを dynamic 型と同様に処理できるようになったため、ほとんどのキャストを回避できます。 COM オブジェクトで dynamic 型を使用する方法の詳細については、C# 機能を使用して Office 相互運用オブジェクトにアクセスする方法に関するの記事を参照してください。

Title 説明
dynamic dynamic キーワードの使用法について説明します。
動的言語ランタイムの概要 DLR の概要について説明します。DLR は動的言語の一連のサービスを共通言語ランタイム (CLR) に追加するランタイム環境です。
チュートリアル: 動的オブジェクトの作成と使用 動的なカスタム オブジェクト、および IronPython ライブラリにアクセスするプロジェクトを作成するための詳細な手順について説明します。