dynamic (C# リファレンス)

dynamic 型を使用すると、コンパイル時の型チェックをバイパスする処理が可能になります。 代わりに、演算は実行時に解決されます。 dynamic 型により、Office オートメーション API などの COM API、IronPython ライブラリなどの動的 API、および HTML ドキュメント オブジェクト モデル (DOM: Document Object Model) へのアクセスが容易になります。

ほとんどの環境で、dynamic 型は object 型のように動作します。 ただし、dynamic 型の式を含む演算はコンパイラによって解決または型チェックされません。 コンパイラは演算に関する情報をまとめてパッケージ化します。その情報が後で実行時に演算を評価するために使用されます。 このプロセスの過程で、dynamic 型の変数は object 型の変数にコンパイルされます。 そのため、dynamic 型はコンパイル時にのみ存在し、実行時には存在しません。

dynamic 型の変数と object 型の変数の違いを次に示します。 コンパイル時に各変数の型を確認するには、WriteLine ステートメントの dyn または obj にマウス ポインターを置きます。 IntelliSense 機能によって、dyn には dynamicobj には object が表示されます。

class Program
{
    static void Main(string[] args)
    {
        dynamic dyn = 1;
        object obj = 1;

        // Rest the mouse pointer over dyn and obj to see their
        // types at compile time.
        System.Console.WriteLine(dyn.GetType());
        System.Console.WriteLine(obj.GetType());
    }
}

WriteLine ステートメントは dyn および obj の実行時の型を表示します。 その時点では、両方が同じ整数型を持ちます。 次の出力が生成されます。

System.Int32

System.Int32

コンパイル時の dynobj の違いを確認するには、前の例の宣言と WriteLine ステートメントの間に次の 2 行を追加します。

dyn = dyn + 3;  
obj = obj + 3;  

obj + 3 に整数およびオブジェクトを追加しようとしたことに対してコンパイル エラーが報告されます。 ただし、dyn + 3 に関するエラーは報告されません。 dyn を含む式はコンパイル時にはチェックされません。これは、dyn の型が dynamic であるためです。

コンテキスト

次の状況では、dynamic キーワードを直接記述するか、構築型のコンポーネントとして記述できます。

  • 宣言では、プロパティ、フィールド、インデクサー、パラメーター、戻り値、ローカル変数、または型制約として記述できます。 次のクラス定義はさまざまな宣言で dynamic を使用します。

    class ExampleClass
    {
        // A dynamic field.
        static dynamic field;
    
        // A dynamic property.
        dynamic prop { get; set; }
    
        // A dynamic return type and a dynamic parameter type.
        public dynamic exampleMethod(dynamic d)
        {
            // A dynamic local variable.
            dynamic local = "Local variable";
            int two = 2;
    
            if (d is int)
            {
                return local;
            }
            else
            {
                return two;
            }
        }
    }
    
  • 明示的な型変換で、変換先の型として記述できます。

    static void convertToDynamic()
    {
        dynamic d;
        int i = 20;
        d = (dynamic)i;
        Console.WriteLine(d);
    
        string s = "Example string.";
        d = (dynamic)s;
        Console.WriteLine(d);
    
        DateTime dt = DateTime.Today;
        d = (dynamic)dt;
        Console.WriteLine(d);
    
    }
    // Results:
    // 20
    // Example string.
    // 2/17/2009 9:12:00 AM
    
  • is 演算子または as 演算子の右側、typeof への引数など、型が値として機能するコンテキストでは構築型の一部として記述できます。 たとえば、次の式では dynamic を使用できます。

    int i = 8;
    dynamic d;
    // With the is operator.
    // The dynamic type behaves like object. The following
    // expression returns true unless someVar has the value null.
    if (someVar is dynamic) { }
    
    // With the as operator.
    d = i as dynamic;
    
    // With typeof, as part of a constructed type.
    Console.WriteLine(typeof(List<dynamic>));
    
    // The following statement causes a compiler error.
    //Console.WriteLine(typeof(dynamic));
    

さまざまな宣言で dynamic を使用する例を次に示します。 また、Main メソッドで、コンパイル時の型チェックと実行時の型チェックの違いを確認できます。

using System;

namespace DynamicExamples
{
    class Program
    {
        static void Main(string[] args)
        {
            ExampleClass ec = new ExampleClass();
            Console.WriteLine(ec.exampleMethod(10));
            Console.WriteLine(ec.exampleMethod("value"));

            // The following line causes a compiler error because exampleMethod
            // takes only one argument.
            //Console.WriteLine(ec.exampleMethod(10, 4));

            dynamic dynamic_ec = new ExampleClass();
            Console.WriteLine(dynamic_ec.exampleMethod(10));

            // Because dynamic_ec is dynamic, the following call to exampleMethod
            // with two arguments does not produce an error at compile time.
            // However, itdoes cause a run-time error. 
            //Console.WriteLine(dynamic_ec.exampleMethod(10, 4));
        }
    }

    class ExampleClass
    {
        static dynamic field;
        dynamic prop { get; set; }

        public dynamic exampleMethod(dynamic d)
        {
            dynamic local = "Local variable";
            int two = 2;

            if (d is int)
            {
                return local;
            }
            else
            {
                return two;
            }
        }
    }
}
// Results:
// Local variable
// 2
// Local variable

使用例を含む詳細については、「dynamic 型の使用」を参照してください。

関連項目

System.Dynamic.ExpandoObject
System.Dynamic.DynamicObject
dynamic 型の使用
object
is
as
typeof
方法: as 演算子と is 演算子を使用して安全にキャストする
チュートリアル: 動的オブジェクトの作成と使用