To find true or false with a boolean nullable variable, I can use
bool? nullable;
bool non-nullable;
non-nullable = (nullable == true);
or
...
non-nullable = (nullable ?? false);
It appears that the result is the same either way:
nullable non-nullable result
-------- -------------------
true true
false false
null false
There certainly is a difference if these are integers, but I don't see any difference for this boolean example.
Is there any performance, or functional, difference between these?
For this boolean example, is there a reason to use one instead of the other?
Edit: fixed code - (nullable ?? true) should be (nullable ?? false)
There is yet another possible expression in your case:
non_nullable = nullable.HasValue && nullable.Value;
I don't exactly know if this will actually be slower than the other specified variants, since the operators on the nullable types are probably overloaded in the Nullable<T> structure as well and would involve method invocations as well. If you want to be sure about that, you will have to investigate and/or benchmark it.
As for the whole discussion about performance: I think it is better to first express your code as "naturally" as possible for future maintenance. Investigate performance improvements only when necessary. As Donald Knuth said: "Premature optimization is the root of all evil."
My advice about which expression to use would be to initially use the one that expresses your intent as clearly as possible. My personal choice would be: nullable == true.
== equality operator in C# and ?? is null-coalescing operator.
From MSDN site
The == (equality) and != (inequality) operators check if their
operands are equal or not.
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.
non-nullable = (nullable == true);
Above statements checks condition if nullable variable contains true then it assigns true value to non-nullable, otherwise assign false.
bool? nullable;
In your case you are creating nullable boolean type variable, it means it can store either bool value or null
non-nullable = (nullable ?? true);
In above statement, set non-nullable to the value of nullable if nullable is NOT null; otherwise, set it to true(which is provided as a constant or default value after ??).
nullable non-nullable result (nullable ?? true) why?
-------- ------------------- ------------------------
true true
false false
null false
(nullable == true) why? (replacing nullable with its value)
true == true, condition satisfies and returns true.
false == true, condition not satisfies and returns false, so non-nullable will be false.
null == true, condition not satisfies and returns false, so non-nullable will be false.
(nullable ?? false) why (nullable ?? true)
true?? false, it checks for value of nullable, it contains value i.e. true then it will assign that value to left hand side operand.
same as first point
null ?? false , now nullable variable contains null value, so it will assign false to left hand side operand
Related
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.
In C#, what is the default value of a class instance variable of type int??
For example, in the following code, what value will MyNullableInt have if it is never explicitly assigned?
class MyClass
{
public int? MyNullableInt;
}
(It seems likely that the answer is almost certainly either null or 0, but which of those is it?)
The default value for int? -- and for any nullable type that uses the "type?" declaration -- is null.
Why this is the case:
int? is syntactic sugar for the type Nullable<T> (where T is int), a struct. (reference)
The Nullable<T> type has a bool HasValue member, which when false, makes the Nullable<T> instance "act like" a null value. In particular, the Nullable<T>.Equals method is overridden to return true when a Nullable<T> with HasValue == false is compared with an actual null value.
From the C# Language Specification 11.3.4, a struct instance's initial default value is all of that struct's value type fields set to their default value, and all of that struct's reference type fields set to null.
The default value of a bool variable in C# is false (reference). Therefore, the HasValue property of a default Nullable<T> instance is false; which in turn makes that Nullable<T> instance itself act like null.
I felt important to share the Nullable<T>.GetValueOrDefault() method which is particularly handy when working with math computations that use Nullable<int> aka int? values. There are many times when you don't have to check HasValue property and you can just use GetValueOrDefault() instead.
var defaultValueOfNullableInt = default(int?);
Console.WriteLine("defaultValueOfNullableInt == {0}", (defaultValueOfNullableInt == null) ? "null" : defaultValueOfNullableInt.ToString());
var defaultValueOfInt = default(int);
Console.WriteLine("defaultValueOfInt == {0}", defaultValueOfInt);
Console.WriteLine("defaultValueOfNullableInt.GetValueOrDefault == {0}", defaultValueOfNullableInt.GetValueOrDefault());
var x = default (int?);
Console.WriteLine("x == {0}", (x == null) ? "null" : x.ToString());
I've come across a curious problem with the following code. It compiles fine although Resharper highlights the code segment (autorefresh == null), notifying me Expression is always false
bool? autorefresh = Properties.Settings.Default.autorefresh;
autorefresh = (autorefresh == null) ? false : autorefresh;
Enabled = (bool)autorefresh;
Any ideas how better to get around this problem?
Edit 07/02/2012 16:52
Properties.Settings.Default.autorefresh
The above is a bool, not a string.
I think what you want is:
Enabled = Properties.Settings.Default.autorefresh ?? false;
In light of your comments, it appears you were unneccessarily assigning the value of autorefresh to a Nullable<bool>. In terms of safeguarding the data, the Settings will return you the default value for that type if it is invalid or missing (which would be false for boolean's). Therefore, your code should simply be:
Enabled = Properties.Settings.Default.autorefresh;
Reason it through:
bool? autorefresh = Properties.Settings.Default.autorefresh;
// ^^^ this is a non-nullable Boolean
Properties.Settings.Default.autorefresh is non-nullable, therefore it will be either true or false.
Therefore the nullable local autorefresh will also be either true or false, since it is initialized to a value that is either true or false.
autorefresh = (autorefresh == null) ? false : autorefresh;
// ^^^^ therefore this test will never succeed
Therefore this is equivalent to:
autorefresh = autorefresh;
which is obviously pointless. (And, as others have pointed out, autorefresh ?? false is the better way to write this code anyway.)
The question is: why do you have the local variable in the first place? Why not simply say:
Enabled = Properties.Settings.Default.autorefresh;
?
bool? autorefresh = Properties.Settings.Default.autorefresh ?? false;
It is safe to make these following comparisons with nullable operators
autorefresh == null
or you may also compare
autorefresh == true
or
autorefresh == false
You could also jut do this:
Enabled = Properties.Settings.Default.autorefresh.GetValueOrDefault(false);
No need to to check for nulls if the nullable value can do it for you.
Nullables have some interesting behavior. I'd have to dig a bit to get you the exact reasons for what you see. Regardless, the correct way to test a nullable is to use the .HasValue method.
You could try this:
bool? autorefresh = Properties.Settings.Default.autorefresh;
Enabled = (!autorefresh.HasValue) ? false : autorefresh.Value;
The autorefresh is nullable type which means that autorefresh.Value can be null.
I think that you can do like this
enable = !autorefresh.HasValue ? false : autorefresh.Value;
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.
I am applying AND operation (&&) between two nullable boolean (bool?) but it is giving me error that
Operator && cannot be applied to operands of type bool? and bool?
How do i apply and operation in my statement that contains two nullable bools?
Also if i have a dialog result like
dialog.ShowDialog () == DialogResult.OK
How can I convert it to nullable bool as i need to put '&&' operator with this in an if condition whose other operand returns a nullable bool?
Here is code:
if (dialog.ShowDialog () == DialogResult.OK && CheckProjectPath(dialog.FileName, true))
the second operand in this if condition is a nullable bool.
How do i apply and operation in my statement that contains two nullable bools?
Well, what do you want to happen? The reason this is illegal is because bad things happen if the first operand is null.
What does x && y mean for nullable Booleans x and y? Well, what does a nullable Boolean mean in the first place? A nullable Boolean means one of three things:
The condition is definitely true
The condition is definitely false
The condition is true or false but we do not know which one
So what does x && y mean? It means "evaluate y only if condition x is true", but if x is nullable then we might not know whether the condition represented by x is true or not.
For example, suppose we have:
gotMoneyInZurich = SalesForNovemberWereMoreThanAMillionBucks() &&
TryToDepositAMillionBucksInASwissBankAccount();
If SalesForNovemberWereMoreThanAMillionBucks is false, then don't try to deposit the money, and we know we have no money in the bank. If it is true, then try to deposit the money; if that fails, then we don't have money in Zurich; if it succeeds, we do.
Now suppose that not all the salespeople have reported their sales figures for November yet. Do we know whether sales for November were more than a million bucks? No. November is in the past; either the sales were, or they weren't more than a million bucks, but right now we don't know. The correct answer is not "false", the correct answer is not "true": the correct answer is "we don't know": null.
So what should this do if null is returned by the first operand? We don't know whether sales were more than a million bucks, so is the right thing to do to try to deposit the money, or to not try to deposit the money? Should you take action on the basis of missing information, or not?
The compiler has no ability to decide this question for you. If you want to not deposit the money if the result is unknown, then you have to say that:(SalesForNovemberWereMoreThanAMillionBucks() ?? false) means "if the result was null, treat it as though it were false".
Similarly, if you say:
if(x && y)
Frob();
and x is true, and y is null, then what should you do? You are saying "Frob only if x and y are both true. x is true, and we don't know whether y is true or not". So should you Frob or not? You don't know. The compiler doesn't know either. If what you want to say is "Frob if x is true and y is either true or null" then say that:
if(x && (y ?? true))
Frob();
Or, "frob if x is true and y is true, but not if y is null" then say that:
if(x && (y ?? false))
Frob();
Now, if you are not using the && operator for the purposes of short-circuiting evaluation then don't use the && operator in the first place. Use the & operator; it always evaluates both sides, so there is no ambiguity here. It is perfectly legal to say x & y if x and y are nullable bools. You still can't use that thing in an if of course; that requires a bool, not a nullable bool. But you can say:
bool? result = x & y;
where x and y are nullable bools.
You can use something like
bool? b1 = ...;
bool? b2 = ...;
bool b = (b1 ?? true) && (b2 ?? false);
You have to pick your own defaults.
How can I convert it to nullable bool as i need to put '&&' operator with this in an if condition whose other operand returns a nullable bool?
You should go the other way: You can't do operations on a nullable operand so you have to try to convert from bool? to bool. The operator ?? is very useful here:
if (dialog.ShowDialog () == DialogResult.OK
&& CheckProjectPath(dialog.FileName, true) ?? false)
Regarding the "null-coalescing operator" ?? :
int? a, b, c;
...
int d = a ?? b ?? c ?? -1;
if a, b and c are all null then d becomes -1. If anyone of them is not null, the first value is used.
I'm just guessing you can try
if ((dialog.ShowDialog() == DialogResult.OK )&&
(CheckProjectPath(dialog.FileName, true) == true ) )
if (dialog.ShowDialog () == DialogResult.OK &&
CheckProjectPath(dialog.FileName, true).GetValueOrDefault())
The && operation is not defined for nulls. Therefore you have to make sure that both booleans are not nullable, and the easiest way to do that is to call the GetValueOrDefault() method of the nullable boolean.
if (dialog.ShowDialog () == DialogResult.OK)
{
var checkProjectPath = CheckProjectPath(dialog.FileName, true);
if (checkProjectPath.HasValue && checkProjectPath)) {/*Your Action*/}
}
If the purpose of the CheckProjectPath function is to validate a Path I cannot see any reason why the result should be bool?