This is mainly a syntactic sugar/best-practice question.
Here is a code example in question:
if (_instanceData?.DataSourceType != null && Util.IsEntityBacked(_instanceData.DataSourceType) {// code}
I understand that the safe navigation operator will continue execution if _instanceData is null, but in this case will the first boolean in the conditional be evaluated as expected? Is this going to successfully null check on both _instanceData and DataSourceType?
Another Example:
if (LockAcquired && _instanceData?.ObjInfo != null) {// code}
In this case, it is possible that _instanceData is null, or it is not, but ObjInfo is null. Is it better practice to just old-fashioned null check both object and property, or will this get the job done as expected?
edit: The question is better described as:
Is if (obj?.prop != null)
equivalent to
if (obj != null && obj.prop != null)
The first is equivalent to
if (_instanceData != null && _instanceData.DataSourceType != null && Util.IsEntityBacked(_instanceData.DataSourceType) {// code}
The second is equivalent to
if (LockAcquired && _instanceData != null && _instanceData.ObjInfo != null) {// code}
So it will check if _instanceData is null, then check if _instanceData.DataSourceType is null, then the last condition. As you said, this is just syntactical sugar so you don't have to write two != null
conditions. The IL code that results is exactly the same, so its a matter of preference whether or not to use the operator.
It does save a TON of space when accessing deeply nested properties, which is where its most useful
if(Parent != null)
{
if(Parent.Child != null)
{
if(Parent.Child.GrandChild != null)
{
Parent.Child.GrandChild.GreatGrandChild.name = "Parent IV";
}
}
}
becomes
Parent?.Child?.GrandChild?.GreatGrandChild.name = "Parent IV";
Saves a lot of space! Even if you collapsed all the ifs into one statement it still saves loads of keystrokes and screen noise.