Reflector 10.0.6.546 -- incorrect C# code involving "Foo?.Bar()"

The .NET 4.7.2 overload  System.Xml.XmlReader.Create(Stream, XmlReaderSettings, String) in System.Xml.dll has the following IL:
.method public hidebysig static class XmlReader Create(class Stream input, class XmlReaderSettings settings, string baseUri) cil managed
{
    .maxstack 8
    L_0000: ldarg.1 
    L_0001: brtrue.s L_000a
    L_0003: newobj instance void XmlReaderSettings::.ctor()
    L_0008: starg.s settings
    L_000a: ldarg.1 
    L_000b: ldarg.0 
    L_000c: ldnull 
    L_000d: ldarg.2 
    L_000e: ldnull 
    L_000f: callvirt instance class XmlReader XmlReaderSettings::CreateReader(class Stream, class Uri, string, class XmlParserContext)
    L_0014: ret 
}
Reflector 10.0.6.546 renders the C# incorrectly:
public static XmlReader Create(Stream input, XmlReaderSettings settings, string baseUri) =>
settings?.CreateReader(input, null, baseUri, null);
It is not correct because the above C# code will do nothing if 'null' is passed for 'settings', whereas the IL constructs a new instance upon which to invoke the 'CreateReader' function. A correct C# version would be:
public static XmlReader Create(Stream input, XmlReaderSettings settings, string baseUri) =>
(settings ?? new XmlReaderSettings()).CreateReader(input, null, baseUri, null);
Technically, I suppose, if you want to mirror the IL exactly, it should be...
public static XmlReader Create(Stream input, XmlReaderSettings settings, string baseUri) =>
(settings ?? (settings = new XmlReaderSettings())).CreateReader(input, null, baseUri, null);
...wherein the new instance is stored in argument slot 1 'settings', but I don't see how this could matter here (since it's not a visible memory location).

Answers

Sign In or Register to comment.