これで、通常どおりメソッドを呼び出すことができます。public class TestClass { public void TestMethod1() { Console .WriteLine( "test method 1" ); } public void TestMethod2() { Console .WriteLine( "test method 2" ); } } * This source code was highlighted with Source Code Highlighter .
public class TestClass { public void TestMethod1() { Console .WriteLine( "test method 1" ); } public void TestMethod2() { Console .WriteLine( "test method 2" ); } } * This source code was highlighted with Source Code Highlighter .
public class TestClass { public void TestMethod1() { Console .WriteLine( "test method 1" ); } public void TestMethod2() { Console .WriteLine( "test method 2" ); } } * This source code was highlighted with Source Code Highlighter .
public class TestClass { public void TestMethod1() { Console .WriteLine( "test method 1" ); } public void TestMethod2() { Console .WriteLine( "test method 2" ); } } * This source code was highlighted with Source Code Highlighter .
public class TestClass { public void TestMethod1() { Console .WriteLine( "test method 1" ); } public void TestMethod2() { Console .WriteLine( "test method 2" ); } } * This source code was highlighted with Source Code Highlighter .
public class TestClass { public void TestMethod1() { Console .WriteLine( "test method 1" ); } public void TestMethod2() { Console .WriteLine( "test method 2" ); } } * This source code was highlighted with Source Code Highlighter .
public class TestClass { public void TestMethod1() { Console .WriteLine( "test method 1" ); } public void TestMethod2() { Console .WriteLine( "test method 2" ); } } * This source code was highlighted with Source Code Highlighter .
public class TestClass { public void TestMethod1() { Console .WriteLine( "test method 1" ); } public void TestMethod2() { Console .WriteLine( "test method 2" ); } } * This source code was highlighted with Source Code Highlighter .
public class TestClass { public void TestMethod1() { Console .WriteLine( "test method 1" ); } public void TestMethod2() { Console .WriteLine( "test method 2" ); } } * This source code was highlighted with Source Code Highlighter .
public class TestClass { public void TestMethod1() { Console .WriteLine( "test method 1" ); } public void TestMethod2() { Console .WriteLine( "test method 2" ); } } * This source code was highlighted with Source Code Highlighter .
public class TestClass { public void TestMethod1() { Console .WriteLine( "test method 1" ); } public void TestMethod2() { Console .WriteLine( "test method 2" ); } } * This source code was highlighted with Source Code Highlighter .
public class TestClass { public void TestMethod1() { Console .WriteLine( "test method 1" ); } public void TestMethod2() { Console .WriteLine( "test method 2" ); } } * This source code was highlighted with Source Code Highlighter .
public class TestClass { public void TestMethod1() { Console .WriteLine( "test method 1" ); } public void TestMethod2() { Console .WriteLine( "test method 2" ); } } * This source code was highlighted with Source Code Highlighter .
予想どおり、すべてが完全にコンパイルされました。 次に、新しい動的キーワードを使用します。
*このソースコードは、 ソースコードハイライターで強調表示されました。
- var test = new TestClass();
- test.TestMethod1();
- test.TestMethod2();
何も変わっていませんか? まったくありません。 すべてが以前とまったく同じ方法でコンパイルされますが、メソッド呼び出しはコンパイルではなく実行時にバインドされます。 つまり、次のように記述した場合:
*このソースコードは、 ソースコードハイライターで強調表示されました。
- 動的テスト= 新しい TestClass();
- test.TestMethod1();
- test.TestMethod2();
とにかくコードは正常にコンパイルされますが、起動後にこの例外が発生します。
*このソースコードは、 ソースコードハイライターで強調表示されました。
- 動的テスト= 新しい TestClass();
- test.TestMethod1();
- test.TestMethod2();
- test.TestMethod3();

ここで何が起こったのですか? Reflectorが語ったことは次のとおりです。
まず、コンパイラはo__SiteContainer0フィールドを生成して、呼び出しの場所に関する情報を保存しました。 オブジェクトを含む変数testを見ると、その型が型オブジェクトになっていることがわかります 。 したがって、実際には、これは動的な型ではなく、コンパイラ側のアシスタントにすぎません。呼び出しているメソッドに関するすべての情報。 呼び出しの場所が示されるとすぐに、変数testで呼び出されます。 ご覧のとおり、コンパイラがすべてを行ってくれました。
*このソースコードは、 ソースコードハイライターで強調表示されました。
- private static void Main( string [] args)
- {
- オブジェクト test = new TestClass();
- if (<Main> o__SiteContainer0。<> p__Site1 == null )
- {
- <Main> o__SiteContainer0。<> P__Site1 = CallSite <Action <CallSite、 object >>。Create( new CSharpCallPayload(Microsoft.CSharp.RuntimeBinder.RuntimeBinder.RuntimeBinder.GetInstance()、 false 、 false 、 "TestMethod1" 、 typeof ( object )、 null ));
- }
- <Main> o__SiteContainer0。<> P__Site1.Target(<Main> o__SiteContainer0。<> P__Site1、テスト);
- if (<Main> o__SiteContainer0。<> p__Site2 == null )
- {
- <Main> o__SiteContainer0。<> P__Site2 = CallSite <Action <CallSite、 object >>。Create( new CSharpCallPayload(Microsoft.CSharp.RuntimeBinder.RuntimeBinder.RuntimeBinder.Gettime()、 false 、 false 、 "TestMethod2" 、 typeof ( object )、 null ));
- }
- <Main> o__SiteContainer0。<> P__Site2.Target(<Main> o__SiteContainer0。<> P__Site2、テスト);
- }
この例では、私たちがやっていることはまったく価値がないように見えますが、コンパイル段階でメソッドがわからない型を使用すると、この機能の威力が発揮されます。 これは、生成されたクラスの場合は動的言語(IronRubyなど)から、またはReflectionを使用する対象からのものである可能性があります。
注釈:記事C#4.0 New Features Part 1.1-dynamic keyword second lookで、著者が新しいテストを実施し、著しく良い結果を示したため、パフォーマンステストに関する部分を翻訳から除外することにしました。
記事翻訳 C#4.0新機能パート1-動的キーワード
私の ブログ からのクロスポスト