最近我遇到了一个有趣的问题,试图通过动态类型实现双重调度。
一点背景知识:在我的一个项目中,我使用 StructureMap 容器和动态类型作为在运行时调度方法调用的干净方式。将 StructureMap 容器更新到较新的版本 (3) 后,我的一些单元测试开始永远挂起。
为了重现这个问题,我创建了 2 个最大程度简化的单元测试:第一个测试永远挂在标有 (*) 的行上,第二个测试按预期通过。它们之间的唯一区别是第一个方法返回的是 StructureMap 的 LambdaInstance 类型的对象。
悬挂测试:
[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:已验证 4.0 和 4.5 目标框架存在问题,已在 VS2010(SP1)、VS2013 中验证。
UPDATE2:简单的控制台应用程序也挂在同一行(所以,这不是测试运行器的问题):
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 上创建了独立示例。