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.
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.
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.
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
See below code first please.
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
class Program
{
public struct MyStruct
{
public List<MyStructItem> Items;
}
public struct MyStructItem
{
public string Value;
}
static void Main(string[] args)
{
List<MyStruct> myList = new List<MyStruct>();
myList.Add(new MyStruct());
//(!) it haven't comipled.
if (myList[0].Items = null){Console.WriteLine("null!");}
//(!) but it have compiled.
if (myList[0].Items != null) { Console.WriteLine("not null!"); }
}
}
}
What is difference between !=null and =null in that case?
thanks.
You are using the assignment operator = instead of the equality operator ==.
Try:
//(!) it haven't comipled.
if (myList[0].Items == null){Console.WriteLine("null!");}
//(!) but it have compiled.
if (myList[0].Items != null) { Console.WriteLine("not null!"); }
The difference is one compiles and one doesn't :-)
C# Operators:
http://msdn.microsoft.com/en-us/library/6a71f45d(v=vs.80).aspx
= null is assignment. You should use == null
You assign the null value to myList[0].Items and tries to use it as bool in if statement. That is why code can not be compiled.
For example, this code compiles successfully:
bool b;
if (b = true)
{
...
}
Because you set true value to b and then check it in if statement.
=null you set the value to null
!= null you check if it is different from null
If you want to compare if it is equal to null, use == null instead of = null.
'=' is for assignment, not for comparing. Use '=='
if (myList[0].Items == null){Console.WriteLine("null!");}
First off, myList[0].Items = null will set the object to null. You probably mean myList[0].Items == null
And regarding the difference, == checked if something is equal. != checks if something is not equal.
For predefined value types, the equality operator (==) returns true if
the values of its operands are equal, false otherwise. For reference
types other than string, == returns true if its two operands refer to
the same object. For the string type, == compares the values of the
strings.
And
The assignment operator (=) stores the value of its right-hand operand
in the storage location, property, or indexer denoted by its left-hand
operand and returns the value as its result. The operands must be of
the same type (or the right-hand operand must be implicitly
convertible to the type of the left-hand operand).
Reference: http://msdn.microsoft.com/en-us/library/6a71f45d(v=vs.71).aspx
= is the assignment operator, you should use the equality operator ==
= null is an assignment. == null is a condition.
if (myList[0].Items != null)
is a negative comparison. It checks if myList[0].Items is not equal to null.
if (myList[0].Items = null)
is an assignment. It would normally assign null to myList[0].Items and return true (in languages like C++), however, in C#, this won't compile (because of this common error).