Search code examples
c#nullnullablenull-conditional-operator

Using null conditional operator("?.") with "function that returns a bool value"


using System;

public class A{
    public bool func(){
        return true;
    }
    

    public int func2(){
        return 10;
    }
}

public class HelloWorld
{
    public static void Main(string[] args)
    {
        A a = new A();
        if(a?.func()){
            Console.WriteLine("true"); // Error
        }
        
        if(a?.func2() == 10){
            Console.WriteLine("true"); // print: True
        }
    }
}

Like above case, I want to use null conditional operator with A function that returns a bool value. But, It throws error only when used with bool returning function.

Can I know why it works like that?

Ironically, It works well with the phrase

if(a?.func() == true){
    Console.WriteLine("true"); // print: true
}

Solution

  • Please, note that even if func returns bool

     a?.func()
    

    returns nullable bool? (true, false and ... null):

     a        : a?.func()
     ------------------------------------------
     null     : null      
     not null : a.func() # either true or false
    

    So you can put

     // if `a` is `null` then `a?.func() is null` 
     // since `null != true` the condition true if and only if
     // `a` is not null and `a.func()` returns true
     if (a?.func() == true)
    

    here .net compares T? and T instances (T is bool in our case). It does it as follow

     // First compute the expression
     bool? result = a?.func()
    
     // Then .net checks if Value is not null
     // and if it is the Value equals to required value 
     if (result.HasValue && result.Value == true) ...
    

    Another way is to use ?? to map null into true or false

     // in case of null - when `a` is null - assume false
     if (a?.func() ?? false)
    

    The very same logic with

     if (a?.func2() == 10)
    

    here a?.func2() returns nullable int? which you compare as == 10, i.e.

    if a is not null and a.func2() returns 10 then...