1

I have the following method which is covered by passing unit tests;

    public static bool TryGetInstance<T>(out T config) where T : class
    {
        return Instance.TryGetInstance(out config);
    }

When I convert this to expression body syntax the unit tests fail?

    public static bool TryGetInstance<T>(out T config) where T : class => 
        Instance.TryGetInstance(out config);

The failing tests are asserting that the method returns true and that the instance returned for config is not null. I had presumed that these compiled to exactly the same IL?

Why might this be happening?

mark_h
  • 5,233
  • 4
  • 36
  • 52
  • They are semantically identical and compile to the same IL on my machine (with optimizations turned on). You'll have to dig deeper (framework version, compiler version, use in context) to find out if that might not be the case on your machine. – Jeroen Mostert Jun 14 '19 at 15:04

1 Answers1

0

They are semantically identical, as shown here

the IL is identical:

    .method public hidebysig static 
        bool TryGetInstance1<class T> (
            [out] !!T& config
        ) cil managed 
    {
        // Method begins at RVA 0x2050
        // Code size 12 (0xc)
        .maxstack 8

        IL_0000: call class Foo P::get_Instance()
        IL_0005: ldarg.0
        IL_0006: callvirt instance bool Foo::TryGetInstance<!!T>(!!0&)
        IL_000b: ret
    } // end of method P::TryGetInstance1

    .method public hidebysig static 
        bool TryGetInstance2<class T> (
            [out] !!T& config
        ) cil managed 
    {
        // Method begins at RVA 0x205d
        // Code size 12 (0xc)
        .maxstack 8

        IL_0000: call class Foo P::get_Instance()
        IL_0005: ldarg.0
        IL_0006: callvirt instance bool Foo::TryGetInstance<!!T>(!!0&)
        IL_000b: ret
    } // end of method P::TryGetInstance2

so: one of two things:

  1. you've broken the compiler or the JIT
  2. the error isn't where you think it is

The second option is far more common. Try reverting just this method change, and see if the problem goes away.

If it does: the folks at Microsoft will be interested in a repro.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Flipping between the two syntax styles consistently caused the unit tests to break. It appears the issue may have been due to my unit tests inadvertently sharing state. When I commented out all but one of my tests it consistently passed. I'm presuming that the order of execution of the tests must have changed between refactoring. I amended my tear down method and now all tests pass, regardless of the syntax style I use. – mark_h Jun 14 '19 at 15:24
  • @mark_h and "option 2" wins another time :) concurrency and ordering on tests is a common cause of failure - most test frameworks have mechanisms to prevent certain tests running in parallel – Marc Gravell Jun 14 '19 at 15:26