What does this code with "?" and "??" mean? - c#

What does this syntax mean? I'm currently coding c# 4.0, when I came by this piece of code.
_data = (SerializationHelper.Deserialize(Request.Form[_dataKey])
? TempData[_dataKey] ?? new ProfileData ()) as ProfileData;
If I were to write it i IF statements how would it be then?
The compiler gives me an error for not writing a : aswell as more things are needed?

?? means if it's null, use the other value. For example
var name = somevalue ?? "Default Name";
If somevalue is null, it will assign the value "Default Name"
Also the single ? is a ternary operator, basically you use it like this:
var example = (conditional statement here) ? value_if_true : value_if_false;
However your code doesn't seem to follow the right syntax for ternary operators when I look at it properly, as Corey says, you may have missed a ? off a ??.

Looks like you missed a ? there. I suspect it was supposed to read:
_data = (SerializationHelper.Deserialize(Request.Form[_dataKey])
?? TempData[_dataKey]
?? new ProfileData()
) as ProfileData;
In C# the operation A ?? B is directly equivalent to (A == null ? B : A), or if (A == null) return B; return A; if you prefer.
So your statement above is equivalent to:
object tmp = SerializationHelper.Deserialize(Request.Form[_dataKey]);
if (tmp == null)
{
tmp = TempData[_dataKey];
if (tmp == null)
_tmp = new ProfileData();
}
_data = tmp as ProfileData;

Related

what does the questionmark do when typing object?.field? [duplicate]

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.

How to write operator for template classes

I want to call constructor of the class only if my object is not null. I can do it with "if else" but I have a lot of assignment like that and want to make it short. How can I write operator like null assignment "??" but it will work reverse.
From
LastMessage = item.LastMessage != null ? new MessageViewModel(item.LastMessage) : null;
To
LastMessage = item.LastMessage !? new MessageViewModel(item.LastMessage);
or (I am not sure this one gonna work but seems nice to me :) )
LastMessage = ? new MessageViewModel(item.LastMessage);

What does question mark and dot operator ?. mean in C# 6.0?

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.

What is the fastest way to get a property from an object after checking that the object isn't null?

What is the fastest way (in terms of minimizing the amount of code statements) to get a property from an object after checking that the object isn't null?
string s = null;
if (null != myObject)
{
s = myObject.propertyName;
}
For reference: Wait for future C# 6.0 feature for null checking with possible ?. syntax:
string result = obj?.ToString();
For now: Use ternary operator:
string result = obj != null ? obj.ToString() : null;
C# does not have a null-propagating operator (although it has been discussed a few times). Frankly, "faster" is not likely to be a factor here, as it will typically end up in the same (or similar enough) IL, but I tend to use:
string s = myObject == null ? null : myObject.PropertyName;
the situation you describe is only one scenario where the operator is useful. It's also handy to replace constructs like this:
if (value != null)
{
return value;
}
else
{
return otherValue;
}
Or
return value != null ? value : otherValue;
with
return value ?? otherValue;

Conditional operator not working as expected

I have the following code where I am using a Conditional Operator to look for null values and assign another value if a null is found. My problem is that it isn't detecting the null value correctly for some reason.
sliderQuestion11.Value = Convert.ToDouble(cs.q11 != null ? cs.q11 : "10");
cs is a class populated by a SQLite query and q11 is a string.
I get a "Value cannot be null" error. Thanks.
EDIT
Thanks for the help everyone. All those answers should have worked but what I had to do is instead of just returning
query.FirstOrDefault()
I had to do the following
CustomerSurvey cs = new CustomerSurvey();
cs.q1 = query.FirstOrDefault().q1 ?? "-10";
cs.q2 = query.FirstOrDefault().q2 ?? "-10";
cs.q3 = query.FirstOrDefault().q3 ?? "-10";
cs.srID = query.FirstOrDefault().srID;
Now this works
sliderQuestion11.Value = Convert.ToDouble(cs.q11 != "-10" ? cs.q11 : "10");
(I know you are going to say why not just set it to 10 but I need to detect a null value elsewhere in the code. That is why I'm using -10)
Maybe you need:
!string.IsNullOrEmpty(cs.q11) ? cs.qll : "10";
The reason for using string.IsNullOrEmpty is because the string may just be empty rather than null.
Full snippet:
sliderQuestion11.Value = Convert.ToDouble(!string.IsNullOrEmpty(cs.q11) ? cs.qll : "10");
You could also try this code:
sliderQuestion11.Value = Convert.ToDouble(cs.q11 ?? "10");
Perhaps it should be
sliderQuestion11.Value = (cs != null && (!string.IsNullOrWhitespace(cs.q11)) ? Convert.ToDouble(cs.q11) : 10);
sliderQuestion11.Value = Convert.ToDouble(!string.IsNullOrWhiteSpace(cs.q11) ? cs.q11 : "10");
This would also check that the string does not contain just 1 or more whitespaces, in addition to the null and empty checks.
Yet another answer: :)
sliderQuestion11.Value = string.IsNullOrWhitespace(cs.q11) ? 10.0 : Convert.ToDouble(cs.q11);

Categories