What does this condition mean?
if (!helper?.Settings.HasConfig ?? false)
P.S.
helper is variable of some class
Settings is some field
HasConfig is field too
Well, ?. is a null-conditional operator
https://msdn.microsoft.com/en-us/library/dn986595.aspx
x?.y
means return null if x is null and x.y otherwise
?? is a null-coalescing operator
https://msdn.microsoft.com/en-us/library/ms173224.aspx
x ?? y
means if x == null return y, otherwise x
Combining all the above
helper?.Settings.HasConfig ?? false
means: return false if
helper == null or
helper.Settings.HasConfig == null
otherwise return
helper.Settings.HasConfig
The code without ?? and ?. if can be rewritten into cumbersome
if (!(helper == null
? false
: (helper.Settings.HasConfig == null
? false
: helper.Settings.HasConfig)))
Check the C# operator list:
x?.y – null conditional member access. Returns null if the left hand operand is null.
x ?? y – returns x if it is non-null; otherwise, returns y.
So helper?.Settings will return null if helper is null otherwise it will return helper.Settings
if helper.Settings is not null and helper.Settings.HasConfig is not null then it will return the value of helper.Settings.HasConfig otherwise will return false.
N.B: if helper?.Settings is null then NULL reference exception will occur.
?. Operator is known as the safe navigation operator introduced in C# 6.
Null Conditional Operator Syntax
The null conditional operator (?.) is colloquially referred to as the "Elvis operator" because of its resemblance to a pair of dark eyes under a large quiff of hair. The null conditional is a form of a member access operator (the .). Here's a simplified explanation for the null conditional operator:
The expression A?.B evaluates to B if the left operand (A) is non-null; otherwise, it evaluates tonull.
Many more details fully define the behavior:
The type of the expression A?.B is the type of B, in cases where B is
a reference type. If B is a value type, the expression A?.B is the
nullable type that wraps the underlying value type represented by B.
The specification for the feature mandates that A be evaluated no
more than once.
The null conditional operator short-circuits, which means that you
can chain multiple ?.operators, knowing that the first null
encountered prevents the remaining (rightmost) components of the
expression from being evaluated.
Example:- Suppose we have a Student class
public class Student
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
Assume that s represents a student. Consider these two statements:
var name = s?.FirstName;
var age = s?.Age;
The variable name is a string. The value of name depends on the value of s. If s is null, name is null. If s is not null, name is the value of s.FirstName. Note that s.FirstName may be null even when s is not.
The variable age is an int? (which is another way of specifying a Nullable). As with name, the value of age depends on the value of s. If s is null, age is an int? with no value. If s is non-null, age is the wrapped value of s.Age.
That's the basics. The power of this feature comes from all the scenarios where this feature enables cleaner code.
It will check if "helper" is not NULL before acessing "Settings" property to avoid NullReferenceException. https://msdn.microsoft.com/en-us/library/dn986595.aspx
"Old" way was like this: if (helper != null && !helper.Settings......).
Related
I have a scenario where I am assigning value to a class property in the below way.
var appResponse = GetAppResponse();
appResponse.LogoImage = GetAppImage(appId);
The problem here is sometimes GetImage(appId) returns null and in that case I don’t want to assign that null value to appResponse.LogoImage, only when GetImage(appId) returns a value then only I want to assign that value.
I can use an If condition to check if GetImage(appId) is returning null or not and then assign the value, but then I will be making 2 calls to the method GetImage() which is not a good approach I feel.
In a single line can I check for null and when it is not null then only assign value to appResponse.LogoImage?
I can use a If condition to check if GetImage(appId) is returning null
or not and then assign the value, but then I will be making 2 calls to
the method GetImage()
Why would you be calling it twice?
Here's just one call:
var appResponse = GetAppResponse();
var appImage = GetAppImage(appId);
if (appImage != null) {
appResponse.LogoImage = appImage;
}
You could use the null-coalescing operator: ??
appResponse.LogoImage = GetAppImage(appId) ?? appResponse.LogoImage;
From the docs:
The null-coalescing operator ?? returns the value of its left-hand operand if it isn't null; otherwise, it evaluates the right-hand operand and returns its result. The ?? operator doesn't evaluate its right-hand operand if the left-hand operand evaluates to non-null.
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?
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
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
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.
I am trying to check the state of an object, if it is null then I need to return null, otherwise, I need to return a Guid or a Bool.
Portrait_Enabled = _SiteImagesModel_ImagesViewModel == null ? null : _SiteImagesModel_ImagesViewModel.Enabled,
Portrait_PrimaryImage = _SiteImagesModel_ImagesViewModel.PrimaryImage ?? null,
Portrait_RecordID = _SiteImagesModel_ImagesViewModel.RecordID ?? null,
Portrait_RelatedImage = _SiteImagesModel_ImagesViewModel.RelatedImage ?? null,
I have tried both the ?? and the ? : and I get a compiler error stating:
Type of conditional expression cannot be determined because there is no implicit conversion between <null> and bool
Operator ?? cannot be applied to operands of type bool and <null>
Operator ?? cannot be applied to operands of type Guid and <null>
Both the Guid and Bool values are Nullable.
The MS Docs explanation about null-coalescing operator (note emphasized part):
A nullable type can represent a value from the type’s domain, or the
value can be undefined (in which case the value is null). You can use
the ?? operator’s syntactic expressiveness to return an appropriate
value (the right hand operand) when the left operand has a nullible
type whose value is null. If you try to assign a nullable value type
to a non-nullable value type without using the ?? operator, you will
generate a compile-time error. If you use a cast, and the nullable
value type is currently undefined, an InvalidOperationException
exception will be thrown.
Since the right-hand operand must return appropriate value of corresponding data type, it can't be set directly as null even the assigned variable has nullable data type (both operands must be have same data type).
Basically when you define a null-coalescing operator as this:
Portrait_PrimaryImage = _SiteImagesModel_ImagesViewModel.PrimaryImage ?? [DefaultValueIfNull];
It will translated as this:
Portrait_PrimaryImage = _SiteImagesModel_ImagesViewModel.PrimaryImage == null ? [DefaultValueIfNull] : _SiteImagesModel_ImagesViewModel.PrimaryImage;
Since both operands in ternary operator & null-coalescing operator must have same type, if you still want null value to be passed, you can cast the right-hand operand to proper type like this:
Portrait_PrimaryImage = _SiteImagesModel_ImagesViewModel.PrimaryImage ?? (bool?)null;
Portrait_RecordID = _SiteImagesModel_ImagesViewModel.RecordID ?? (Guid?)null;
Portrait_RelatedImage = _SiteImagesModel_ImagesViewModel.RelatedImage ?? (bool?)null;
Note that null is not at the same type as Nullable<bool>, you need to cast into bool? to get same data type.
As in your case, ternary operator usage just enough, no need to use null-coalescing operator when the second operand is null:
Portrait_Enabled = _SiteImagesModel_ImagesViewModel == null ? null : (bool?)_SiteImagesModel_ImagesViewModel.Enabled;
Portrait_RecordID = _SiteImagesModel_ImagesViewModel == null ? null : (Guid?)_SiteImagesModel_ImagesViewModel.RecordID;
Portrait_RelatedImage = _SiteImagesModel_ImagesViewModel == null ? null : (bool?)_SiteImagesModel_ImagesViewModel.RelatedImage;
References:
Type of conditional expression cannot be determined because there is no implicit conversion between 'int' and <null>
How to set null to a GUID property
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?
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
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
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.
I have a class with a string property. I use the coalesce operator when reading from it as it might be null, but it still throws me an NullRefrenceExeption.
string name = user.Section.ParentSection.Name ?? string.Empty;
To be more specific, its the ".ParentSection" that's null so is it because it don't even have ".name" ? If that's the case should i test ".ParentSection" first with an if block?
I assume there are something about the Coalesce operator i dont understand, hope someone can shed some light on whats going wrong here.
To be more specific, its the ".ParentSection" that's null so is it
because it don't even have ".name" ?
Yes.
If that's the case should i test ".ParentSection" first with an if
block?
Yes.
You'll need to check if Section and ParentSection are null. You could use an if-statement for this or write an extension method like this:
public static class MaybeMonad
{
public static TOut With<TIn, TOut>(this TIn input, Func<TIn, TOut> evaluator)
where TIn : class
where TOut : class
{
if (input == null)
{
return null;
}
else
{
return evaluator(input);
}
}
}
You would use this method like so:
string name = user.With(u => u.Section)
.With(s => s.ParentSection)
.With(p => p.Name) ?? string.Empty;
I think it's a lot cleaner than an if-statement with a lot of &&.
Some further reading: http://www.codeproject.com/Articles/109026/Chained-null-checks-and-the-Maybe-monad
You need to check if user, user.Section, or user.Section.ParentSection are null before you can use the null coalescing operator on a property of user.Section.ParentSection.
Nested property access is not safe if any of the objects accessed are null this will throw a NullReferenceException. You will have to explicitly test for the outer objects to be not null.
E.g.:
string name = string.Empty;
if(user!=null && user.Section!=null && user.Section.ParentSection !=null)
name = user.Section.ParentSection.Name ?? string.Empty;
In general I would try to avoid nested access to properties, you are violating the Law of Demeter. Some refactoring might make this unnecessary in the first place.
The ?? operator checks if the left side is null and if so returns the right one, if not the left one.
In your case the left-side is the "Name" property in the object user.Section.ParentSection and this is null.
In those cases either think on what might be null or do something like this:
string name = user == null
|| user.Section == null
|| user.ParentSection == null
|| user.Section.ParentSection.Name == null
? string.Empty
: user.Section.ParentSection.Name;
(yeah it's ugly I know)
Chances are user or user.Section or user.Section.ParentSection is a null value.
The ?? operator doesn't prevent checks like:
if (user != null && user.Section != null && user.Section.ParentSection != null){
Make sure that everything up to the string property is valid and exists, then you can use ??. You can't call (null).Name, no matter how many times you try.
Yes you need to check if Section or ParentSection are null before you check Name
It is probably best to do something like this:
if(user!=null && user.Section!=null && user.Section.ParentSection!=null)
{
string name = user.Section.ParentSection.Name ?? string.Empty;
}
The null coalescing operator takes a statement like:
a = b ?? c;
What this says is "evaluate b; if it has a non-null value then assign that to a. Otherwise assign the value of c to a".
However within your b you're using a user object which may be null that has a section object that may be null that has a parent section property that may be null that had a name property that may be null. If you wanted to check all of these (and typically you should) then you can do something like:
string name = string.Empty;
if (user != null &&
user.Section != null &&
user.Section.ParentSection != null)
{
name = user.Section.ParentSection.Name ?? string.Empty;
}
As soon as the IF check fails it will not check further and therefore you don't get a NullReferenceException when you assume an object is present and then try to access one of its properties.