引き続き、dynamicについてです。
が、今回は前回の内容と、あまり変わりません。
dynamicを用いて、動的なプログラミングを行う際に
.NETは内部でRuntime Lookupという動作を行います。
これは、dynamicとして定義されたオブジェクトが実際には
何の型なのかを調べる処理です。
ホワイトペーパーに記述されている内容だと以下の過程を
踏んでいくようです。
- COM Objects
- IDispatch経由でアクセスする。
- Dynamic Objects
- IDynamicObject経由でアクセスする。
- Plain Objects
- Reflection経由でアクセスする。
また、オーバーロードメソッドを呼び出したりする際も
解決が行われます。(Overload resolutionというようです。)
解決手順は、上記の内容で行われ、最終的に合致した
オーバーロードメソッドが実行に呼ばれます。
以下、サンプルです。
using System; namespace DynamicLookup02 { class Program { static void Main(string[] args) { (new Program()).Execute(); } private void Execute() { // // Runtime Lookup // // dynamicを利用している場合、目的のオブジェクトを特定するために // 以下の手順で型の特定が行われる。 // // 1.COM Objects // そのオブジェクトがCOMオブジェクトの場合は、IDispatch経由でアクセスが行われる。 // // 2.Dynamic Objects // そのオブジェクトがIDynamicObjectを実装している場合、そのオブジェクト自身に問い合わせる。 // (このインターフェースは、IronPythonやIronRubyのような動的言語にてサポートされる) // // 3.Plain Objects // そのオブジェクトが普通の.NET Objectである場合、Reflectionを用いてアクセスが行われる。 // // 下記の場合は、Plain ObjectであるのでReflectionを用いて実行時にアクセスが行われる。 // SampleA a = new SampleA(); dynamic b = new SampleB(); a.Method1(b); // // Overload resolution // // 引数の型がdynamicの状態で、オーバーロードメソッドを呼び出すと // Overload resolution(オーバーロード解決)が行われる。 // // 下記の例では、dynamicである変数a2は実際にはSampleAのインスタンスで // あるので、実行時に解決が行われSampleBクラスの // internal void Execute(SampleA a) // が呼び出される。 // dynamic a2 = new SampleA(); dynamic b2 = new SampleB(); b2.Execute(a2); Console.WriteLine("Press any key to exit..."); Console.ReadLine(); } } class SampleA { public void Method1(dynamic b) { b.Execute(this); } } class SampleB { internal void Execute(SampleA a) { Console.WriteLine("Sample B : {0}", a.ToString()); } internal void Execute(SampleC c) { Console.WriteLine("Sample B : {0}", c.ToString()); } } class SampleC { } }