?? Operator with 2 strings? - c#

In this .NET code:
return Redirect("~/Home" ?? "JaneDoe");
If I'm reading the docs right, the "??" operator appears to operate similarly to IsNull in SQL:
IsNull("~/Home", "JaneDoe")
"~Home" and "JaneDoe" are simply strings, right? There's no condition in the return Redirect code where "JaneDoe" will be what's passed into "Redirect", is there? I'm not sure what to make of this snippet, I can only presume it's a placeholder for something to come later.
This code is from a .NET-MVC project in development, part of a .cs file that is a LoginController.

Yes, this is just bad code. That will always be equivalent to
return Redirect("~/Home");
I'm slightly surprised the compiler isn't smart enough to give a warning about it, to be honest. It would be nice if it could tell that a constant non-null expression was being used on the LHS of the null-coalescing operator.

The ?? operator is called the null-coalescing operator and is used to define a default value for a nullable value types as well as reference types. It returns the left-hand operand if it is not null; otherwise it returns the right operand.
In your case, it will never return JaneDoe

Yes, you're reading it correctly. That will always return "~/Home", presumably it was planned to change it to a variable at some point.

This would always use the "~/Home" string. The null-coalescing operator (??) selects the left side if it is non-null, or the right side if it is null.

Correct, the expression will never return "JaneDoe".

Related

equality and null check (Ruby-on-Rails and c#)

I was using the ||= operator in Ruby on Rails and I saw that C# have something similar.
Is ||= in Ruby on Rails equals to ?? in C# ?
What is the difference if there is one?
Based on what I have read here, the x ||= y operator works like:
This is saying, set x to y if x is nil, false, or undefined. Otherwise set it to x.
(modified, generalized, formatting added)
The null-coalescing operator ?? on the other hand is defined like:
The ?? operator is called the null-coalescing operator. It returns the left-hand operand if the operand is not null; otherwise it returns the right hand operand.
(formatting added)
Based on that there are two important differences:
The ?? does not assign, it is like a ternary operator. The outcome can be assigned, but other things can be done with it: assign it to another variable for instance, or call a method on it; and
The ?? only checks for null (and for instance not for false), whereas ||= works with nil, false and undefined.
But I agree they have some "similar purpose" although || in Ruby is probably more similar with ??, but it still violates (2).
Also mind that the left part of the null-coalescing operator does not have to be a variable: on could write:
Foo() ?? 0
So here we call a Foo method.
Simple answer... yes and no.
The purpose of the ||= operator in Ruby-on-Rails is to assign the left-hand operand to itself if not null, otherwise set it to the the right-hand operand.
In C#, the null coalescing operator ?? makes the same check that ||= does, however it's not used to assign. It serves the same purpose as a != null ? a : b.

Safe Navigation Operator with Any()

Hey Everyone I thought that this code would be valid in any case because it is casted to bool
parameter.Request?.InnerData?.Any() == false
Instead this code is casted to type bool?
Can tell me someone why? (this is main question)
Is there better way to check this instead of something like this?
var isThereInnerData = parameter.Request?.InnerData?.Any();
if (isThereSegments == null || isThereSegments == false)
With a null-conditional operator, null propagates. You can't end up with a non-nullable type if you use the null-conditional operator - this is the same behaviour in languages where null operations are "safe" by default (SQL, Objective-C, ...). So the result is default(bool?) if parameter.Request is null, or parameter.Request.InnerData is null. Otherwise, you get true or false, but by using the null-conditional operator you already assume the result can in fact be null, so the compiler must accomodate that. Since bool can't be null, it is changed into a nullable bool (bool?).
The solution is simple - think about what logical value a null should have, and use that:
if (parameter.Request?.InnerData?.Any() ?? true)
In this case, a null value is interpreted as true, but you can also use false if you want. Alternatively, instead of the null-coalescing operator, you can use GetValueOrDefault, whatever feels better for you.
Here is what C# reference says about ?. operator:
x?.y – null conditional member access. Returns null if the left hand
operand is null.
Since at compile time the compiler doesn't knows whether the expression will evaluate to a non-null value, the compiler infers the type as Nullable<bool>
Since you are chaining the ?. operator this line from msdn documentation is relevant too:
The null-condition operators are
short-circuiting. If one operation in a chain of conditional member
access and index operation returns null, then the rest of the chain’s
execution stops. Other operations with lower precedence in the
expression continue. For example, E in the following always executes,
and the ?? and == operations execute.
bool is a value type and per default cannot be compared with null. C# converts your return value to bool? to give you the option to support both.

What is the boolean result of assign null to a variable

I almost sure those two codes are equivalent, but not sure why.
First is the how I usually do it, i think the safe and more readable way.
string userLine = Console.ReadLine();
while (userLine != null) {
// do things with userLine
userLine = Console.ReadLine();
}
Second one works but not sure why. Because Im comparing an assigment to null.
string userLine;
while ((userLine = Console.ReadLine()) != null) {
// do things with userLine
}
I believe you are thinking that the assignment operation doesn't return any value or returns a Boolean value. That is not correct.
See: = Operator
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.
So your statement
while ((userLine = Console.ReadLine()) != null) {
is getting the value from Console.ReadLine assigning the result to userLine and returning the same value, which is compared with null.
The reason behind it works well is because, parenthesis () have highest operator precedence. Once assignment is done, compile will compare the the value of that variable to the null.
Having assignment in parenthesis chains your assignment. And that is the reason, it works.
Not only on Assignment, it works with return values too.
return (value = Console.ReadLine());
But yes, the first one is more readable approach.
The second code works because != operator has left associativity.
So that first
(userLine = Console.ReadLine())
execute, after that comparison happen.
And you are right the first approach is more readable.
If you want to get more information about associativity please refer https://msdn.microsoft.com/en-us/library/2bxt6kc4.aspx
In most likely scenario it is a function call and on return of the function the return value is stored either in done data GPR(general purpose register) or at top of stack. So, the next statement will just use that location and compare against null. Now you see fit generated code it doesn't make any difference... If you want to be sure, generate the assembly file during compilation and check for yourself. All compilers provide option to keep generated files...

Expression expected in ?: operator

why can't I have something like:
Some_Function ? myList.Add(a) : throw new Exception();
Why can't I throw exception in else part of ?: operator? what is the main purpose of ?: operator?
Suggestion
If anybody else wondered about the same thing, beside reading the answers below, i suggest that you read this post as well..
Expression Versus Statement
The other answers and comments are of course true (we can refer to the documentation), though my understanding of the question is more like, "why does it have to be that way?".
According to the C# 5.0 specification, the conditional operator forms an expression, not a statement. I suspect that the reason why it's not a statement, thus preventing you from doing something like a ? b() : throw e is simply because we already have a statement construct for achieving basically the same thing; namely, if..else.
if (a) { b(); } else { throw e; }
The benefit of the conditional operator is that it can be used within statements or other expressions.
bool? nb = GetValue();
if (nb ?? (a ? b() : c())) { throw e; }
Because it is defined as:
null-coalescing-expression ? expression : expression
As you can read in ?: Operator (C# Reference):
The conditional operator (?:) returns one of two values depending on the value of a Boolean expression.
One of both expression is evaluated depending on the boolean value of null-coalescing-expression.
Since neither of your two code fragments are expressions that evaluate to a value (List.Add() is void and an exception doesn't evaluate to a value either), this can't compile.
You need to remember that Ternary operator must return something and List.Add is a void method so it fails. Both the sides must be compatible and should return something.
The MSDN says:
The condition must evaluate to true or false. If condition is true,
first_expression is evaluated and becomes the result. If condition is
false, second_expression is evaluated and becomes the result.
And myList.Add(a) is not an expression.
See ?: Operator on MSDN. Its clearly explained there.
The conditional operator (?:) returns one of two values depending on the value of a Boolean expression. Following is the syntax for the conditional operator.
condition ? first_expression : second_expression;
The condition must evaluate to true or false. If condition is true, first_expression is evaluated and becomes the result. If condition is false, second_expression is evaluated and becomes the result. Only one of the two expressions is evaluated.
Either the type of first_expression and second_expression must be the same, or an implicit conversion must exist from one type to the other.
You can express calculations that might otherwise require an if-else construction more concisely by using the conditional operator. For example, the following code uses first an if statement and then a conditional operator to classify an integer as positive or negative.
The conditional operator (?:) returns one of two values depending on the value of a Boolean expression. Following is the syntax for the conditional operator.
The condition must evaluate to true or false. If condition is true, first_expression is evaluated and becomes the result. If condition is false, second_expression is evaluated and becomes the result. Only one of the two expressions is evaluated.
Either the type of first_expression and second_expression must be the same, or an implicit conversion must exist from one type to the other.
You can express calculations that might otherwise require an if-else construction more concisely by using the conditional operator. For example, the following code uses first an if statement and then a conditional operator to classify an integer as positive or negative.

Does the ?? operator guarantee only to run the left-hand argument once?

For example, given this code:
int? ReallyComplexFunction()
{
return 2; // Imagine this did something that took a while
}
void Something()
{
int i = ReallyCleverFunction() ?? 42;
}
... is it guaranteed that the function will only be called once? In my test it's only called once, but I can't see any documentation stating I can rely on that always being the case.
Edit
I can guess how it is implemented, but c'mon: we're developers. We shouldn't be muddling through on guesses and assumptions. For example, will all future implementations be the same? Will another platform's implementation of the language be the same? That depends on the specifications of the language and what guarantees it offers. For example, a future or different platform implementation (not a good one, but it's possible) may do this in the ?? implementation:
return ReallyComplexFunction() == null ? 42 : ReallyComplexFunction();
That, would call the ReallyComplexFunction twice if it didn't return null. (although this looks a ridiculous implementation, if you replace the function with a nullable variable it looks quite reasonable: return a == null ? 42 : a)
As stated above, I know in my test it's only called once, but my question is does the C# Specification guarantee/specify that the left-hand side will only be called once? If so, where? I can't see any such mention in the C# Language Specification for ?? operator (where I originally looked for the answer to my query).
The ?? operator will evaluate the left side once, and the right side zero or once, depending on the result of the left side.
Your code
int i = ReallyCleverFunction() ?? 42;
Is equivalent to (and this is actually very close to what the compiler actually generates):
int? temp = ReallyCleverFunction();
int i = temp.HasValue ? temp.Value : 42;
Or more simply:
int i = ReallyCleverFunction().GetValueOrDefault(42);
Either way you look at it, ReallyCleverFunction is only called once.
The ?? operator has nothing to do with the left hand. The left hand is run first and then the ?? operator evaluates its response.
In your code, ReallyCleverFunction will only run once.
It will be only called once. If the value of ReallyCleverFunction is null, the value 42 is used, otherwise the returned value of ReallyCleverFunction is used.
It will evaluate the function, then evaluate the left value (which is the result of the function) of the ?? operator. There is no reason it would call the function twice.
It is called once and following the documentation I believe this should be sufficient to assume it is only called once:
It returns the left-hand operand if the operand is not null; otherwise
it returns the right operand.
?? operator
It will only be run once because the ?? operator is just a shortcut.
Your line
int i = ReallyCleverFunction() ?? 42;
is the same as
int? temp = ReallyCleverFunction();
int i;
if (temp != null)
{
i = temp.Value;
} else {
i = 42;
}
The compiler does the hard work.
Firstly, the answer is yes it does guarantee it will only evaluate it once, by inference in section 7.13 of the official C# language specification.
Section 7.13 always treats a as an object, therefore it must only take the return of a function and use that in the processing. It says the following about the ?? operator (emphasis added):
• If b is a dynamic expression, the result type is dynamic. At run-time, a is first evaluated. If a is not null, a is converted to dynamic, and this becomes the result. Otherwise, b is evaluated, and this becomes the result.
• Otherwise, if A exists and is a nullable type and an implicit conversion exists from b to A0, the result type is A0. At run-time, a is first evaluated. If a is not null, a is unwrapped to type A0, and this becomes the result. Otherwise, b is evaluated and converted to type A0, and this becomes the result.
• Otherwise, if A exists and an implicit conversion exists from b to A, the result type is A. At run-time, a is first evaluated. If a is not null, a becomes the result. Otherwise, b is evaluated and converted to type A, and this becomes the result.
• Otherwise, if b has a type B and an implicit conversion exists from a to B, the result type is B. At run-time, a is first evaluated. If a is not null, a is unwrapped to type A0 (if A exists and is nullable) and converted to type B, and this becomes the result. Otherwise, b is evaluated and becomes the result.
As a side-note the link given at the end of the question is not the C# language specification despite it's first ranking in a Google Search for the "C# language specification".

Categories

Resources