最近、動的型を介して二重ディスパッチを実装しようとして、興味深い問題に遭遇しました。
ちょっとした背景: 私のプロジェクトの 1 つで、StructureMap コンテナーと動的型を使用して、実行時にメソッド呼び出しをディスパッチするクリーンな方法として使用しています。StructureMap コンテナーを新しいバージョン (3) に更新した後、一部の単体テストが永久にハングし始めました。
問題を再現するために、2 つの最大限に単純化された単体テストを作成しました。最初のテストは (*) でマークされた行で永久にハングし、2 番目のテストは期待どおりにパスします。それらの唯一の違いは、最初のメソッドが LambdaInstance タイプの StructureMap のオブジェクトを返すことです。
ぶら下げテスト:
[TestFixture]
[Category("Unit")]
public class when_trying_to_call_method_with_dynamic_argument1
{
private class A {}
private static LambdaInstance<object> Method(A obj)
{
throw new NotImplementedException();
}
[Test]
[ExpectedException(typeof(NotImplementedException))]
public void should_succeed()
{
var instance = (dynamic)new A();
Method(instance); //(*)hangs forever on this line
}
}
合格テスト:
[TestFixture]
[Category("Unit")]
public class when_trying_to_call_method_with_dynamic_argument2
{
private class A {}
private static object Method(A obj)
{
throw new NotImplementedException();
}
[Test]
[ExpectedException(typeof(NotImplementedException))]
public void should_succeed()
{
var instance = (dynamic)new A();
Method(instance);
}
}
どのようにそれが可能でしょうか?それとも疲れて寝たいだけですか?
とにかく、特定のライブラリで特定の問題の修正を見つけようとするのではなく、概念的かつ教育的な問題です。
UPDATE1: VS2010(SP1)、VS2013 で検証された、4.0 & 4.5 ターゲット フレームワークに問題が存在することを確認しました。
更新 2: シンプルなコンソール アプリケーションも同じ行でハングしています (したがって、テスト ランナーの問題ではありません)。
class Program
{
private class A { }
private static LambdaInstance<object> Method(A obj)
{
throw new NotImplementedException();
}
static void Main(string[] args)
{
var instance = (dynamic)new A();
Method(instance); //(*)hangs forever on this line
}
}
また、 GitHubでスタンドアロンの例を作成しました。