This project is read-only.
4

Resolved

Extension method doesn't work with null-propagation operator

description

I couldn't get this this code to compile. Seems like extension method calls are not recognized after null propagation operator or the actual error message is misleading (it says that the extension method was not found which is not true since it is defined correctly).
class C
{
    public object Get()
    {
        return null;
    }
}

class CC
{
}

static class CCExtensions
{
    public static object Get(this CC c)
    {
        return null;
    }
}


class Program
{
    static void Main(string[] args)
    {
        C c = null;
        var cr = c?.Get();   //this compiles (Get is instance method)

        CC cc = null;
        var ccr = cc?.Get(); //this doesn't compile

        Console.ReadLine();
    }
}
Compiler error message is:
'ConsoleApplication1.CC' does not contain a definition for 'Get' and no extension method 'Get' accepting a first argument of type 'ConsoleApplication1.CC' could be found (are you missing a using directive or an assembly reference?)

comments

SSL wrote Jun 10, 2014 at 8:21 PM

This is probably by design, but should have its own error message (Extension methods cannot be called with the null-propagation operator)

http://stackoverflow.com/a/24148944/34397

ControlFlow wrote Jun 11, 2014 at 1:21 AM

This is a bug.
There is NO REASON to 'by design'-ify this issue.
Most of the extension methods are throwing ArgumentNullException anyway, designing extension method handling null value of this-parameter is a code smell.

MgSam wrote Jun 11, 2014 at 4:58 AM

@ControlFlow Strongly disagree with your point about extension methods. Allowing them to handle null is in fact one of their best uses in some scenarios. Adding an IsNullOrEmpty() extension method on to string is extremely useful and far more intuitive than calling the static method. Like any feature, you have to be aware of how you're using it.

Przemyslaw wrote Jun 11, 2014 at 10:32 AM

@MgSam - yes, they are handy in such case. But there are also many places where the exact opposite is true. See IEnumerable<T>.FirstOrDefault(...) method for example. So, let the user decide how to call extension methods. With regular '.' or the new and handy '?.'
As ControlFlow said - there are no technical limitations to implement support for extension methods with '?.' Let user decide if null safe call is handy for him or not.