? Operator VS ?? Operator Usage - c#

The following statement works:
Class.ID = odrDataReader["ID"] == null ? 0 : Convert.ToInt32(odrDataReader["ID"]);
But the following does not:
Class.ID = odrDataReader["ID"] as int? ?? 0; //ID is always 0
Any one can explain why ?? operator always returns 0 even when ID column is not null?
Solution(suggested by Kirk):
Class.ID = Convert.ToInt32(odrDataReader["ID"] ?? 0);

In first one you use Convert.ToInt32(odrDataReader["ID"]) in second one you use odrDataReader["ID"] as int?.
From what you say first one is correct, so you should use Convert in second too.
Actualy I think first is fine, because it would look weird if you really wanted to use ?? operator.
Edit:
To explain a bit odrDataReader["ID"] as int? is NOT a conversion. It will always return null if odrDataReader["ID"] is string.

It all depends on the type of the ID column. If it was indeed of type int?, then you should be able to do this with no problems:
Class.ID = (int?)odrDataReader["ID"] ?? 0;
However it is more likely that this is not the case and is a different type (I'd guess string). A string is clearly not a int? and thus odrDataReader["ID"] as int? always returns null and you get the value 0. As Euphoric mentions, the as operator only does reference/boxing conversions. If this is the case, using ?? is not an option for you and you must use the first expression.

It's definitely because you are doing odrDataReader["ID"] as int? - that is the difference between the two statements, and using the as keyword is not the same as doing a Convert.
If you want to use ?? you could try
Class.ID = Convert.ToInt32(odrDataReader["ID"] ?? 0);

Coalescing operator is new operator added in C#2.0. Coalescing operator is also known as ??.
Nullable<int> a = null;
Nullable<int> b = 10;
int c = a ?? b.Value;
Coalescing operator
Coalescing operator work some what similar to ternary operator but it works only with the Nullable types only. so its sort hand operator to deal with Nullable types only.
check my blog post : Coalescing operator - ??

the ?? operator is the null-coalescing operator. It defines a default value if the value is found to be null. Int32 is a value type in .NET, which normally can't take a null value, so the int? designates an Int32 that can be null.

Misread the question. I'm guessing it's because you're casting odrDataReader["ID"] to int? before checking it. You should try skipping the cast, though I doubt that's what's really the problem.

Related

C#, is this "if... else..." block equivalent to one line of code using null-coalescing operator

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.

HasValue() or ?? operand when dealing with nullable types in LINQ-to-Entity,

I have had the following code to assign a value to nullable int variable:
ParentCommentId = lac.ParentCommentId ?? lac.ParentCommentId.Value,
However, with this code I was receiving the Nullable object must have a value error.
Then, I revised the code as follows:
ParentCommentId = lac.ParentCommentId.HasValue ? lac.ParentCommentId.Value : null,
And, now everything works fine. I wonder why ?? operand does not work in this case. Am I using it wrong? In what cases, ?? would be more suitable?
Nullable object must have a value is a runtime exception that occurs when you try to access .Value of a nullable with .HasValue false.
Your code:
ParentCommentId = lac.ParentCommentId ?? lac.ParentCommentId.Value
gets translated to:
if (lac.ParentCommentId.HasValue)
{
ParentCommentId = lac.ParentCommentId.Value;
}
else
{
ParentCommentId = lac.ParentCommentId.Value;
}
As you can see, both branches are doing the same and you would be accessing .Value even if HasValue is false (and will result in that exception).
The operator ?? is used to take the first not-null value. You can write
var value = value1 ?? value2 ?? value3;
The first of value1, value2, value3 that is not null will be assigned to value, if all are null then value will be set to null.
ParentCommentId = lac.ParentCommentId ?? lac.ParentCommentId.Value,
I wonder why ?? operand does not work in this case.
When you use the null-coalescing operator ?? it's shorthand for a short set of steps, the steps in a general sense do the following
Is lac.ParentCommentId something that can be null?
Yes -> Continue
No -> Give a compiler error saying you can't use the ?? operator on something that can't be null because it's the null-coalescing operator.
Is lac.ParentCommentId null?
Yes -> Continue
No -> Set the value of ParentCommentId to the value of lac.ParentCommentId, if they're the same type.
Set the value of ParentCommentId to the value of lac.ParentCommentId.Value, if they're the same type.
When you break down what the ?? operator does you can see that it runs into a problem right around step 2.
What you want is when lac.ParentCommentId has a value, to set ParentCommentId to lac.ParentCommentId.Value.
However, when you use the ?? that's not what you're doing. Instead it looks like you're saying 'When lac.ParentCommentId has a value, set ParentCommentId to lac.ParentCommentId'.
There is a way we can work around this, and it's actually pretty simple, because lac.ParentCommentId is already a nullable value we can simply use
ParentCommentId = lac.ParentCommentId ?? AlternativeValue
If we also consider that null is an acceptale value for ParentCommentId, we can actually simplify this even more for a more elegant solution and use:
ParentCommentId = lac.ParentCommentId
Edit: the following only applies to LINQ-to-Objects and not entity-framework. It remains as additional information on the ? null coelescing operator. Thanks to Ivan Stoev for pointing that out!
If the lac.ParentCommentId.Value is a null-able value you could instead use this:
ParentCommentId = lac?.ParentCommentId.Value ?? AlternativeValue,
What that does is it checks to see if ANY of lac ParentCommentId OR Value are null, and if ANY of them are null, use the alternative value.

C# Null propagating operator / Conditional access expression & if blocks

The Null propagating operator / Conditional access expression coming in c#-6.0 looks like quite a handy feature. But I'm curious if it will help solve the problem of checking if a child member is not null and then calling a Boolean method on said child member inside an if block:
public class Container<int>{
IEnumerable<int> Objects {get;set;}
}
public Container BuildContainer()
{
var c = new Container();
if (/* Some Random Condition */)
c.Objects = new List<int>{1,2,4};
}
public void Test()
{
var c = BuildContainer();
//Old way
if ( null != c && null != c.Objects && c.Objects.Any())
Console.Write("Container has items!");
//C# 6 way?
if (c?.Object?.Any())
Console.Write("Container has items!");
}
Will c?.Object?.Any() compile? If the propagating operator short circuits (I assume that's the right term) to null then you have if (null), which isn't valid.
Will the C# team address this concern or am I missing the intended use case for the null propagating operator?
It won't work this way. You can just skip the explanation and see the code below :)
As you know ?. operator will return null if a child member is null. But what happens if we try to get a non-nullable member, like the Any() method, that returns bool? The answer is that the compiler will "wrap" a return value in Nullable<>. For example, Object?.Any() will give us bool? (which is Nullable<bool>), not bool.
The only thing that doesn't let us use this expression in the if statement is that it can't be implicitly casted to bool. But you can do comparison explicitly, I prefer comparing to true like this:
if (c?.Object?.Any() == true)
Console.Write("Container has items!");
Thanks to #DaveSexton there's another way:
if (c?.Object?.Any() ?? false)
Console.Write("Container has items!");
But as for me, comparison to true seems more natural :)
Null-conditional operator would return null or the value at the end of expression. For value types It will return result in Nullable<T>, so in your case it would be Nullabe<bool>. If we look at the example in the document for Upcoming Features in C# (specified here), it has an example:
int? first = customers?[0].Orders.Count();
In the above example, instead of int, Nullable<int> would be returned. For bool it will return Nullable<bool>.
If you try the following code in Visual Studio "14" CTP:
Nullable<bool> ifExist = c?.Objects?.Any();
The result of the above line would be a Nullable<bool>/bool?. Later you can do the comparison like:
Using null-coalescing operator ??
if (c?.Object?.Any() ?? false)
Using Nullable<T>.GetValueOrDefault Method
if ((c?.Objects?.Any()).GetValueOrDefault())
Using comparison against true
if (c?.Objects?.Any() == true)
var x = c?.Objects?.Any() is going to give you a nullable boolean, and as others have said, this means you can use an equality operator like this
x == true
or you can use null coalescing like this to have your result not be nullable
var x = c?.Objects?.Any() ?? false
But, personally, I think that 3-state (nullable) booleans are code smell. Even if this one is practically invisible, its existence should encourage you to think about what you are actually trying to do and determine if a nullable boolean is actually the way to go. In this case, I think that what you really want to do is something like this -
var objects = c?.Objects ?? Enumerable.Empty<Object>();
if (objects.Any())
{
...
}
Put that in an extension method and it will be even more succinct -
public static bool IsNullOrEmpty<T>(this IEnumerable<T> collection)
{
return !(collection ?? Enumerable.Empty<T>()).Any()
}

Rewrite HasValue to the ?? Operators

Is it safe to rewrite the following code:
bool b = foo.bar.HasValue ? foo.bar.Value : false;
to
bool b = foo.bar.Value ?? false;
where bar is the nullable type bool?
The easiest fix there is
bool b = foo.bar.GetValueOrDefault();
which is also actually cheaper than .Value as it omits the has-value check. It will default to default(T) , which is indeed false here (it just returns the value of the underlying T field, without any checks at all).
If you need a different default to default(T), then:
var value = yourNullable.GetValueOrDefault(yourPreferredValue);
What you want is:
bool b = foo.bar ?? false;
This is (surprisingly) safe and an intended use for 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.
Source: http://msdn.microsoft.com/en-us/library/ms173224.aspx
In the case of Nullable<T>, it is functionally equivalent to Nullable<T>.GetValueOrDefault(T defaultValue).
The code:
bool b = foo.bar.Value ?? false;
Will cause a compiler-error, because you cannot apply the operator to value types, and Nullable<T>.Value always returns a value-type (or throws an exception when there is no value).
No - this is not safe.
The line:
bool b = foo.bar.Value ?? false;
will throw an InvalidOperationException if foo.bar has no value.
Instead use
var b = foo.bar ?? false;
Update - I just learned about .GetValueOrDefault(); from the other answers - that looks like a very good suggestion to use!
Update 2 - #ProgrammingHero's answer is also correct (+1 added!) - the line:
bool b = foo.bar.Value ?? false
actually won't compile - because of Error 50 Operator '??' cannot be applied to operands of type 'bool' and 'bool'
Nope.
The Value property returns a value if
one is assigned, otherwise a
System.InvalidOperationException is
thrown.
From: http://msdn.microsoft.com/en-us/library/1t3y8s4s%28v=vs.80%29.aspx
So if hasValue is false then you will get an exception thrown in your second one when you try to run it.
ffoo.bar ?? false would be more safer to use
bar.Value ?? false
has compilation error, because left operand of ?? operator should be of reference or nullable type.
Maybe you have a look at this article in Stackoverflow too - it is an elegant null checking in the style obj.IfNotNull(lambdaExpression) - returning the object you want if obj is not null otherwise just null (but without throwing an exception).
I used it with the Entity Framework if you're accessing a referenced entity, e.g.
var str=Entity1.Entity2.IfNotNull(x=>x.EntityDescription) ?? string.Empty
which returns EntityDescription contained in Entity2 which is referenced by Entity1 - or an empty string if any object Entity1 or Entity2 is null. Without IfNotNull you would get a long and ugly expression.
The extension method IfNotNull is defined there as follows:
public static TOut IfNotNull<TIn, TOut>(this TIn v, Func<TIn, TOut> f)
where TIn : class
where TOut: class
{
if (v == null) return null; else return f(v);
}
Update:
If you update the code to C# version 6.0 (.NET Framework 4.6 - but seems to support older frameworks 4.x too), there is a new operator available which makes this task easy: The "elvis" operator ?..
It works as follows:
var str=(Entity1.Entity2?.EntityDescription) ?? string.Empty
In this case, if Entity2 is null, evaluation stops and (...) becomes null - after which the ?? string.empty part replaces null by string.Empty. In other words, it works the same way as .IfNotNull(...) would.
foo.bar.Value represents the non-nullable value when there is one, and throws an InvalidOperationException if there’s no real value.

What does ?? mean in C#? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
What do two question marks together mean in C#?
What does the ?? mean in this C# statement?
int availableUnits = unitsInStock ?? 0;
if (unitsInStock != null)
availableUnits = unitsInStock;
else
availableUnits = 0;
This is the null coalescing operator. It translates to: availableUnits equals unitsInStock unless unitsInStock equals null, in which case availableUnits equals 0.
It is used to change nullable types into value types.
The ?? operator returns the left-hand operand if it is not null, or else it returns the right operand.
?? Operator (C# Reference)
according to MSDN, 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.
Check out
http://msdn.microsoft.com/en-us/library/ms173224.aspx
it means the availableUnits variable will be == unitsInStock unless unitsInStock == 0, in which case availableUnits is null.

Categories

Resources