ChatGPT解决这个技术问题 Extra ChatGPT

What does question mark and dot operator ?. mean in C# 6.0?

With C# 6.0 in the VS2015 preview we have a new operator, ?., which can be used like this:

public class A {
   string PropertyOfA { get; set; }
}

...

var a = new A();
var foo = "bar";
if(a?.PropertyOfA != foo) {
   //somecode
}

What exactly does it do?

If you are intersted in coverting a nullable bool bool ? into a bool value - stackoverflow.com/questions/6075726/…

J
John Cummings

It's the null conditional operator. It basically means:

"Evaluate the first operand; if that's null, stop, with a result of null. Otherwise, evaluate the second operand (as a member access of the first operand)."

In your example, the point is that if a is null, then a?.PropertyOfA will evaluate to null rather than throwing an exception - it will then compare that null reference with foo (using string's == overload), find they're not equal and execution will go into the body of the if statement.

In other words, it's like this:

string bar = (a == null ? null : a.PropertyOfA);
if (bar != foo)
{
    ...
}

... except that a is only evaluated once.

Note that this can change the type of the expression, too. For example, consider FileInfo.Length. That's a property of type long, but if you use it with the null conditional operator, you end up with an expression of type long?:

FileInfo fi = ...; // fi could be null
long? length = fi?.Length; // If fi is null, length will be null

@SLaks: I thought it was "conditional null" but I could be wrong. Last time I checked the Roslyn language features docs, it hadn't been renamed to either. Maybe the source is the authority here - will check.
@SLaks: Sure. In SyntaxKind it's apparently ConditionalAccessExpression which is annoyingly neither of them...
i preferred the name "Elvis" operator :P
Just for the record I've seen five different names for this operator: safe navigation, null-conditional, null propagation, conditional access, Elvis.
Useful to note... you can also use the null conditional on arrays, like: a?[x]
E
Erik Philips

It can be very useful when flattening a hierarchy and/or mapping objects. Instead of:

if (Model.Model2 == null
  || Model.Model2.Model3 == null
  || Model.Model2.Model3.Model4 == null
  || Model.Model2.Model3.Model4.Name == null)
{
  mapped.Name = "N/A"
}
else
{
  mapped.Name = Model.Model2.Model3.Model4.Name;
}

It can be written like (same logic as above)

mapped.Name = Model.Model2?.Model3?.Model4?.Name ?? "N/A";

DotNetFiddle.Net Working Example.

(the ?? or null-coalescing operator is different than the ? or null conditional operator).

It can also be used out side of assignment operators with Action. Instead of

Action<TValue> myAction = null;

if (myAction != null)
{
  myAction(TValue);
}

It can be simplified to:

myAction?.Invoke(TValue);

DotNetFiddle Example:

using System;

public class Program
{
  public static void Main()
  {
    Action<string> consoleWrite = null;
    
    consoleWrite?.Invoke("Test 1");
    
    consoleWrite = (s) => Console.WriteLine(s);
    
    consoleWrite?.Invoke("Test 2");
  }
}

Result:

Test 2

Basically, I have applied ?. operator after Model as well. I am trying to know that whether it can be applied directly to the model or does it only work with the navigation properties?

The ? or null conditional operator operators on the left value, regardless of the type of value. And the compiler doesn't care what the value is on the right. It's simple compiler magic (meaning it does something you can already do, just in a simplified why).

For example

  var a = model?.Value;

is the same as saying

  var a = model == null ? null : model.Value;

In the second case the evaluation of checking for null has no associate with the value returned. The null conditional operator basically just always return null if the left value is null.

The type of member (Method, Field, Property, Constructor) .Value is irrelevant.

The reason your DotNetFiddle example doesn't work is because the compiler being use for the .Net 4.7.2 isn't compatible with the c# version that support the null conditional operator. Changing it to .Net 5, works:

https://dotnetfiddle.net/7EWoO5


To save people looking up what the ?? is.. It is the null-coalescing operator and will return Name if it is not null, otherwise it will return "N/A".
@Erik Philips I think you need to add || Model.Model2.Model3.Model4.Name == null to have the same logic, otherwise in case Model.Model2.Model3.Model4.Name is null, mapped.Name will stay null
@ErikPhilips Not on the same page I guess. Please try to see what happens in both your cases if Model.Model2.Model3.Model4.Name is null.
The result is "N/A", again PLEASE READ THE FIRST COMMENT. DotNetFiddle.Net Working Example.
@ErikPhilips: That has nothing to to with the first comment, as this does not relate to your first example. In this you would jump into the else-branch and have mapped.Name = Model.Model2.Model3.Model4.Name -> mapped.Name = null, while you second example would substitute to mapped.Name = "N/A". See the edited DotNetFiddle
N
Neuron

This is relatively new to C# which makes it easy for us to call the functions with respect to the null or non-null values in method chaining.

old way to achieve the same thing was:

var functionCaller = this.member;
if (functionCaller!= null)
    functionCaller.someFunction(var someParam);

and now it has been made much easier with just:

member?.someFunction(var someParam);

I strongly recommend this doc page.


Quick question..var user = db.Users.Where(m=>m.id == id).FirstOrDefault(); Console.WriteLine(user?.id); Would this work or ?. only work with navigation properties? Kindly check this fiddle: dotnetfiddle.net/2BblBv