Recently I came across an interesting problem trying to implement double dispatch via dynamic type.
A little background: in one of my projects I use StructureMap container and dynamic type as a clean way to dispatch method calls at runtime. After updating StructureMap container to the newer version(3), some of my unit-tests started to hang eternally.
To reproduce the problem I created 2 maximally simplified unit-tests: The first test hangs forever on the line marked with (*), the second test passes as expected. The only difference between them is that method of the first one returns StructureMap's object of type LambdaInstance.
The hanging test:
[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
}
}
The passing test:
[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);
}
}
How it could be possible? Or I am just tired and need to go sleep?
Anyway, it's conceptual and educational question, rather than willing to find fix for the particular problem in the particular library.
UPDATE1: Verified that problem exists for 4.0 & 4.5 target Frameworks, verified in VS2010(SP1), VS2013.
UPDATE2: Simple console application is hanging on the same line as well(so, it's not the problem with test-runner):
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
}
}
Also I created standalone example on GitHub.