0

Are function arguments always evaluated in a C# null-conditional function call?

i.e. in the following code:

obj?.foo(bar());

Is bar evaluated if obj is null?

Nathan Phillips
  • 11,899
  • 1
  • 31
  • 24

3 Answers3

3

The spec specifies that

A null_conditional_member_access expression E is of the form P?.A. Let T be the type of the expression P.A. The meaning of E is determined as follows:

  • [...]

  • If T is a non-nullable value type, then the type of E is T?, and the meaning of E is the same as the meaning of:

    ((object)P == null) ? (T?)null : P.A
    

    Except that P is evaluated only once.

  • Otherwise the type of E is T, and the meaning of E is the same as the meaning of:

    ((object)P == null) ? null : P.A
    

    Except that P is evaluated only once.

In your case, P is obj. A is foo(bar()). If we expand both cases:

((object)obj == null) ? (T?)null : obj.foo(bar())

((object)obj == null) ? null : obj.foo(bar())

By the semantics of the ternary operator, when obj is null, the third operand, obj.foo(bar()) will not be evaluated.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
-1

Running test code indicates that in the Microsoft compiler at least the arguments are not evaluated, however the C# specification doesn't seem to specify this as required behaviour.

Nathan Phillips
  • 11,899
  • 1
  • 31
  • 24
  • Quote from your link: _The null-conditional operators are short-circuiting. That is, if one operation in a chain of conditional member or element access operations returns null, the rest of the chain doesn't execute. In the following example, B is not evaluated if A evaluates to null and C is not evaluated if A or B evaluates to null: `A?.B?.Do(C);`_ Does that not cover it? – Astrid E. Sep 15 '22 at 11:28
  • At second glance, you asked about _function_ arguments. I agree that is not specifically discussed. Given that quote, though, I would expect the same behavior for function arguments as for non-function arguments. – Astrid E. Sep 15 '22 at 11:31
  • 1
    It's worth noting that the link isn't to the actual specification - it's the language reference. The spec is at https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#1177-null-conditional-member-access or (source) https://github.com/dotnet/csharpstandard/blob/draft-v7/standard/expressions.md#1177-null-conditional-member-access – Jon Skeet Sep 15 '22 at 12:01
  • 1
    What you've linked to is the language reference, *not* the spec. When you're seeking precision, the spec is what you should be looking at. I was just finding the right part to quote but [Sweeper beat me to it](https://stackoverflow.com/a/73730746/15498) – Damien_The_Unbeliever Sep 15 '22 at 12:01
-1

No.

There is no reason to evaluate bar() if obj is null.

Create the example, in dotnetfiddle or elswhere, and make bar output something. Nothing will be outputed.

LosManos
  • 7,195
  • 6
  • 56
  • 107