Search code examples
c#out-parametersexpression-body

Converting block body method with out parameter to expression body method causes out parameter to be null


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?


Solution

  • 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.