5

Extension methods with . operator always called, even if object is null without throwing NullReferenceException. By using operator ?. it will never called. For example:

using System;

public class Program
{
    public static void Main()
    {
        A a = null;
        a.b(); // works
        a?.b(); // doesn't work
    }
}

public class A { }

public static class ext
{
    public static void b(this A a)
    {
        Console.WriteLine("I'm called");
    }
}

Why extension method isn't called in this case? Is this an ambiguos feature?

Konstantin Zadiran
  • 1,485
  • 2
  • 22
  • 35
  • 2
    You can see the compiled>decompiled code at [Try Roslyn](http://tryroslyn.azurewebsites.net/#f:r/K4Zwlgdg5gBAygTxAFwKYFsDcAobAHYAIwBswBjGM4gQxBBgAUAnAeyievWwG9sZ+YBEuRgpqyEQDcWYACYwAstUgAKAJR8BvATpgBBGNRgBeGBGDFiOXQOoA6QuswwA9C5gB3FkwDWITTbUAPwOTq7usiyoIBAA5Mie3j4BMAC+2On4RKQUVLT0BtxpuEI5osjiInl0MKgAHsg8KaUiYhIU0nIwjsgAFmAFhho62jYwAMIsECAsxKh2AOpMYGgAMpCoKgBEAJKx6JTUlqiyW2rWAumpQAAA) – Kobi Dec 30 '15 at 10:20
  • 3
    Well `?.` operator checks if value is `null` *before* doing anything, so why it should work ? Something to read : http://stackoverflow.com/questions/847209/in-c-what-happens-when-you-call-an-extension-method-on-a-null-object and https://msdn.microsoft.com/en-us/library/dn986595.aspx – Fabjan Dec 30 '15 at 10:23
  • 2
    What is the practical usage of having extension method which doesn't use this object at all. – Yeldar Kurmangaliyev Dec 30 '15 at 10:23
  • 1
    I don't understand why there is not `NullReferenceException` at `a.b();`? – Shaharyar Dec 30 '15 at 10:32
  • 1
    @Shaharyar, because nothing is being invoked on `a`. – Paulo Morgado Dec 30 '15 at 17:47

2 Answers2

16

Your expression a?.b() which uses ?. operator translates to equivalent:

if(a != null)
{
  a.b();
}

so this is why your method does not get called.

Marcin Zablocki
  • 10,171
  • 1
  • 37
  • 47
1

Calling an extension method has the following edge-case: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#11893-extension-method-invocations

Note: Unlike an instance method invocation, no exception is thrown when expr evaluates to a null reference. Instead, this null value is passed to the extension method as it would be via a regular static method invocation. It is up to the extension method implementation to decide how to respond to such a call.

This explains why your compiler will make a.b() work (it emits a call IL op). And it's probably save to assume that the a?.b() will actually include a runtime null check, thus not executing the method.

Marcel Greter
  • 275
  • 1
  • 10