4

C#プログラミング言語でBillWagnerは次のように述べています。

多くの人が動的バインディングと型推論を混同しています。型推論は静的にバインドされます。コンパイラはコンパイル時にタイプを決定します。例えば:

var i = 5;             //i is an int (Compiler performs type inference)
Console.WriteLine(i);  //Static binding to Console.WriteLine(int)

コンパイラーは、iが整数であると推測します。変数iのすべてのバインディングは、静的バインディングを使用します。

さて、この情報と私自身が作ったダイナミックなシーンリオを考えると:

        dynamic i = 5;       //Compiler punts
        Console.WriteLine(i);//This is now dynamically bound

型推論は静的にバインドされていることがわかっています。これは、動的変数が型推論を使用して型を判別する方法がないことを意味します。型推論を使用せずに動的型を解決するにはどうすればよいですか?

更新
試行して明確にするために...実行時に、どのタイプが正しいかをどういうわけか理解する必要がありますか?リテラルを割り当てるので、ランタイムはそれがであると5推測できます。その型推論は動的バインディングではありませんか?iint

4

1 に答える 1

7

ビルはどのような区別をしていますか?

ビルが行っている違いは、多くの人が次のように考えていることです。

var x = Whatever();
x.Foo();

Whateverによって実行時に返されるオブジェクトのタイプに基づいて、実行時にどのメソッドFooを呼び出すかが決まります。それは真実ではない; それは

dynamic x = Whatever();
x.Foo();

var単に「実行時に計算する」ではなく、「コンパイル時に型を計算して代入する」という意味です。

だから私が持っているなら

dynamic i = 5;
Console.WriteLine(i);

何が起こるのですか?

コンパイラは、道徳的に次のようなコードを生成します。

object i = (object)5;
DynamicCallSite callSite = new DynamicCallSite(typeof(Console), "WriteLine"));
callSite.Invoke(i);

それよりも少し複雑です。一つには、コールサイトはキャッシュされます。しかし、これはあなたにそれの味を与えます。

呼び出しメソッドはi、経由でその型を要求してからGetType、リフレクションオブジェクトを理解できるC#コンパイラの特別なバージョンを起動します。Consoleこれは、 namedのメンバーに対してオーバーロード解決を行い、最初にintとして入力された場合に呼び出されたであろうWriteLineオーバーロードを判別します。Console.WriteLinei

次に、その呼び出しを表す式ツリーを生成し、式ツリーをデリゲートにコンパイルし、それを呼び出しサイトにキャッシュして、デリゲートを呼び出します。

2回目にこれを行うと、キャッシュされた呼び出しサイトはそのキャッシュを調べ、最後iにintであったときに、特定のデリゲートが呼び出されたことを確認します。したがって、2回目は、呼び出しサイトの作成と過負荷解決の実行をスキップし、デリゲートを呼び出すだけです。

詳細については、以下を参照してください。

http://ericlippert.com/2012/10/22/a-method-group-of-one/

http://ericlippert.com/2012/11/05/dynamic-contagion-part-one/

http://ericlippert.com/2012/11/09/dynamic-contagion-part-two/

この機能の歴史的な視点は、ChrisとSamのブログから入手できます。

http://blogs.msdn.com/b/cburrows/archive/tags/dynamic/

http://blogs.msdn.com/b/samng/archive/tags/dynamic/

彼らは多くの実装を行いました。ただし、これらの記事の一部は、古い設計の選択を反映しています。残念ながら、「ファントムメソッド」アルゴリズムを使用したことはありません。(優れたアルゴリズムではありませんが、優れた名前です!)

于 2013-02-13T18:02:32.403 に答える