With the introduction of Null-Conditional Operators in C#, for the following evaluation,
if (instance != null && instance.Val != 0)
If I rewrite it this way,
if (instance?.Val != 0)
it will be evaluated to true if instance is a null reference; It behaves like
if (instance == null || instance.Val != 0)
So what is the right way to rewrite the evaluation using this new syntax?
Edit:
instance is a field of a big object which is deserialized from JSON. There are quite a few pieces of code like this, first check if the field is in the JSON, if it is, check if the Val property does NOT equal to a constant, only both conditions are true, do some operation.
The code itself can be refactored to make the logical flow more "making sense" as indicated by Peter in his comment, though in this question I am interested in how to use null-conditional operators with !=.
With Null-Conditional operator returned value can always be null
if ((instance?.Val ?? 0) != 0)
If instance was null, then instance?.Val will also be null (probably int? in your case). So you should always check for nulls before comparing with anything:
if ((instance?.Val ?? 0) != 0)
This means:
If instance?.Val is null (because instance is null) then return 0. Otherwise return instance.Val. Next compare this value with 0 (is not equal to).
You could make use of null coallescing operator:
instance?.Val ?? 0
When instance is null or instance is not null but Val is, the above expression would evaluate to 0. Otherwise the value of Val would be returned.
if ((instance?.Val).GetValueOrDefault() != 0)
the ? conditional operator will automatically treat the .Val property as a Nullable.
Related
I'm curious if this block of code:
//value is an object, maybe null, maybe not
if (value == null)
item.PassageStimuliTitle = "";
else
item.PassageStimuliTitle = value.ToString().Trim();
is equivalent to this line:
item.PassageStimuliTitle = (string)(value ?? value.ToString().Trim());
I've used if... else... for a long time, but recently came across the null-coalescing operator in C#. I've used it to prevent null exception errors for params passed in method calls. I think using it in the example above is equivalent, and condenses the code from 4 lines to 1. Thanks for reading. Curious to hear feedback.
I'm expecting the two examples to be equivalent, but curious if there's something I'm missing.
No, the null-coalescing operator expression is not written correctly. a ?? b means "evaluate to b if a is null, otherwise evaluate to a". Therefore, your use of the null-coalescing operator will always produce a NullReferenceException if value is null - your code will try to evaluate value.ToString() when value is null.
Your use of ?? would translate to something like the following if statement, which I think you'd agree is quite non-sensical:
if (value == null) {
item.PassageStimuliTitle = (string)value.ToString().Trim();
} else {
item.PassageStimuliTitle = (string)value;
}
With certain assumptions, the if statement can be rewritten as:
item.PassageStimuliTitle = value?.ToString().Trim() ?? "";
This uses the null conditional operator ?.. If value is null, then the entire value?.ToString().Trim() expression is null, and hence the RHS of the ?? is evaluated. Otherwise, .ToString().Trim() is called on value.
item.PassageStimuliTitle = value != null ? value.ToString().Trim() : "";
From #Charles Mager comment:
item.PassageStimuliTitle = value?.ToString().Trim() ?? ""
Is a better and clearer one-liner.
You used ?? operator incorrectly.
In this example:
result = left_value ?? right_value;
?? operator returns left_value if it is NOT null.
If left_value is null, it returns right_value.
So, in your case, if variable value is of type object, it should be:
item.PassageStimuliTitle = (value ?? "").ToString().Trim();
Here is a successfully compiled code fiddle.
I have code as below in C#:
If (this._university != Null and this._university.department !=null &&
this._university.department.class !=null &&
this._university.department.class.student != null &&
this._university.department.class.student.name != null &&
this._university.department.class.student.name.firstname != null &&
this._university.department.class.student.name.firstname !=String.empty)
{
// selecting first letter of Firstname
var F_firstname = this._university.department.class.student.name.firstname[0].tostring();
}
But the code looks very bad for checking null object.Do we have better way for null check for objects?
If you are using one of the later C# versions. Maybe this looks better with Null-conditional Operators. However, it is an unusual bit of code anyway and might point to the need to refactor a little.
var firstName = this._university?.department?.class?.student?.name?.firstname;
if(!string.IsNullOrEmpty(firstName))
{
...
}
Further Reading
Null-conditional Operators
Tests the value of the left-hand operand for null before performing a
member access (?.) or index (?[]) operation; returns null if the
left-hand operand evaluates to null.
String.IsNullOrEmpty
Indicates whether the specified string is null or an Empty string.
This question already has answers here:
Deep null checking, is there a better way?
(16 answers)
Closed 5 years ago.
Can anyone tell me how do I optimize below code.
if (report != null &&
report.Breakdown != null &&
report.Breakdown.ContainsKey(reportName.ToString()) &&
report.Breakdown[reportName.ToString()].Result != null
)
As others have mentioned, you can use the ?. operator to combine some of your null checks. However, if you're after optimizing for performance, you should avoid the double dictionary lookup (ContainsKey and index access), going for a TryGetValue instead:
MyType match = null; // adjust type
if (report?.Breakdown?.TryGetValue(reportName.ToString(), out match) == true &&
match?.Result != null)
{
// ...
}
Ayman's answer is probably the best you can do for C# 6, for before that what you have there is pretty much the best you can do if all those objects are nullable.
The only way to optimize this further is to be checking if those objects are null before even calling the code, or better yet proofing your platform so this particular function shouldn't even be called in the first place if the values are null.
If you are just getting the value from from the dictionary however you can also simplify with the null coalescing operater '??'
Example:
MyDictionary['Key'] ?? "Default Value";
Thus if the Value at that entry is null you'll get the default instead.
So if this is just a fetch I'd just go
var foo =
report != null &&
report.Breakdown != null &&
report.Breakdown.ContainsKey(reportName.ToString()) ?
report.Breakdown[reportName.ToString()].Result ?? "Default" :
"Default";
But if you are actually doing things in the loop, then yeah you're pretty much at the best you can get there.
For C# 6 and newer, you can do it this way:
if (report?.Breakdown?.ContainsKey(reportName.ToString()) == true &&
report.Breakdown[reportName.ToString()].Result != null)
You can use null conditional operator but only on C# 6
if ( report?.Breakdown?.ContainsKey(reportName.ToString()) == true &&
report.Breakdown[reportName.ToString()].Result != null )
Can you try below? Also probably better to ship it to a method.
// unless report name is already a string
string reportNameString = reportName.ToString();
if ( report?.Breakdown?.ContainsKey(reportNameString) &&
report.Breakdown[reportNameString].Result != null )
{
// rest of the code
}
Observation: If text is null, this method returns True. I expected False.
return text?.IndexOf('A') != -1;
When I reflect the above line using ILSpy (or inspect the IL), this is the generated code:
return text == null || text.IndexOf('A') != -1;
Here is what I really need to meet my expectation:
return text != null && text.IndexOf('A') != -1;
Question: Does someone have a good explanation about why the Null Conditional code generated the OR expression?
Full Sample at: https://dotnetfiddle.net/T1iI1c
The line above really involves two operations: a null-conditional operator method call, and a comparison. What happens if you store the result of the first operator as an intermediate variable?
int? intermediate = text?.IndexOf('A');
return intermediate != -1;
Clearly if text is null then intermediate will also be null. Comparing this with any integer value using != will return true.
From MSDN (emphasis mine):
When you perform comparisons with nullable types, if the value of one of the nullable types is null and the other is not, all comparisons evaluate to false except for != (not equal).
This code can be written using the null-conditional operator as long as you can use a different operator to ensure a comparison with null evaluates to false. In this case,
return text?.IndexOf('A') > -1;
will return the output you expected.
Something like the ternary operator (?:) or the null coalescing operator (??). It seems silly to me to take up two lines and be so wordy when the other operators exist.
EDIT:
Since it's requested, here's two possible examples of what I hope that I can find
var variable ?= mightBeNull;
or
var variable = mightBeNull != null ? mightBeNull
Really, it's either something that can be used to assign a value, if it's not null, to a variable or an If without an Else packaged nicely in an operator.
The ??= operator is coming to C# 8.
int? i = null; // i = null
i ??= 0; // i = 0
i ??= 1; // i = 0
// different ways of writing 'i ??= 0;':
i = i ?? 0;
if (i == null) i = 0;
So you want this?
if (other != null)
someVariable = other;
You could do the following, but I'd argue that the above is better due to clarity and possible side effects:
someVariable = other ?? someVariable;
The above might cause side effects if someVariable is a property and either the get or set can cause side effects; this shouldn't be important if your property follows the ordinary guidelines. Or, as Servy points out, even if it's a field, it could created different semantics in a multithreaded app. I should note that in the first example, you read other twice, which also has the potential for complexity to enter (though a smaller potential than the latter example).
I bet this is what you are looking for.
Let's say we have a function, myFunction that says whether the argument passed input is null or not. If input is null, it will return "Input is null!", else it will return "Input is not null".
This is the normal approach:
public String myFunction(string input) {
if (input == null)
return "Input is null!";
else
return "Input is not null";
}
And this is the other approach (What you are looking for):
public String myFunction(string input) {
return (input == null) ? "Input is null!" : "Input is not null";
}
It is called (?: conditional operator).
To assign a value to a variable only if it is not null, you would need to use an if. Neither the conditinal nor the null coalesce operators would do that.
if(somethingElse != null) something = somethingElse;
There is no specific operator in C# that does exactly this.
In Visual Studio 2015 C# there is a new operator called the Null-Conditional that does what you are asking. It is the ?. or ? operator.
int? length = customers?.Length; // null if customers is null
Customer first = customers?[0]; // null if customers is null
int? count = customers?[0]?.Orders?.Count(); // null if customers, the first customer, or Orders is null
Currently useable in previous versions of C# but not an operator but rather a one liner would be to use the ? : statement
?: operator
condition ? first_expression : second_expression;
AssingningTO = (someVar == null) ? null: someVar; // if null assign null ELSE assign someVar
AssingningTO = (someVar == null) ? String.Empth(): someVar; // if null assign empty string else someVar
Nullable types can represent all the values of an underlying type, and an additional null value.
http://msdn.microsoft.com/en-us/library/2cf62fcy.aspx