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;
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 many places throught app I've seen stuffs like this:
(int)f.Status == something.Status
And this Status property is:
public int? Status { get; set; }
What I am trying to achieve is comparing nullable ints (int?) so that they are equal only if they both have a value and the value is the same. In particular, if they are both null I want them to be identified as not equal.
What is the best way to do that?
I'd suggest using:
f.Status == something.Status
assuming the two properties are either int or int?.
C# will allow you to compare int vs int? without an explicit cast.
For future readers, this answer was written prior to the OP making clear that comparing null to null was expected to return false.
This code is risky and it can give you NullReferenceException if f.Status is null.
You can check first if it has value -> f.Status.HasValue before casting to integer.
You can do this to prevent exception:
if (f.Status.HasValue && f.Status == something.Status)
{
}
I'd suggest rewriting condition into this:
f.Status.HasValue && something.Status.HasValue && f.Status == something.Status
It would prevent you from exceptions.
If any of statuses is just and int and not an int?, then you can omit HasValue check.
Already given answer suggests using simple ==, but it will return true in case both are nulls, opposite to suggested. You have to decide if that's desired behaviour.
As mentioned it could be simplified to
f.Status.HasValue && f.Status == something.Status
in case of both nulls result will be the same.
This question has already been answered, but here's another way of comparing nullable values.
if ((f.Status ?? 0) == something.Status){
//enter code here
}
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
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Which is preferred: Nullable<>.HasValue or Nullable<> == null?
I know questions like this have been asked many times. But I never found an answer to how to check if a nullable bool is null or not.
Here is an answer I have to this:
bool? nullableBool;
if (nullableBool == true){
}else if (nullableBool == false){
}else{
}
But I was wondering if there is a better and more straight to the point way in order to minimize useless codes?
Thanks.
if (!nullableBool.HasValue)
{
// null
}
You also can directly compare it with null.
That's not a nullable bool, it's an unassigned bool and your code won't compile. You need to use bool? or Nullable<bool>.
bool? nullableBool = null; // or = true or = false
if (nullableBool.HasValue)
{
if (nullableBool.Value)
// true
else
// false
}
else
// null
Firstly, the bool you have used is not nullable. To create a nullable bool you can do one fo the following:
Nullable<bool> nullableBool;
or the shorthand version:
bool? nullableBool;
either of these can then be checked to see if it has a value using the following:
if(nullableBool.HasValue)
{
//nullableBool has been assigned a value
}
Your current approach is not recommended. If you need a nullable state then use a nullable bool. If you want to use a standard bool then be sure to assign it a value. I am surprised you don't get a compile error in Visual Studio with that code.
Try this plz:
if (!nullableBool.HasValue)
{
// your code
}
This code throwing out an error:
bool status1 = (bool)Cache["cache_req_head"];
bool status2 = (bool)Cache["cache_super"];
bool status3 = (bool)Cache["cache_head"];
This is how the cache variables were set:
if (checkreqhead == true)
{
Cache["cache_req_head"] = true;
}
else if (checksuper == true)
{
Cache["cache_super"] = true;
}
else if (checkhead == true)
{
Cache["cache_head"] = true;
}
Coming from PHP background, this is awkward. The error is:
Object reference not set to an instance of an object
I'm certain it is something really simple, but probably I can't spot it.
THANKS ALL FOR HELPING :)
"Object reference not set to an instance of an object" is c# lingo for "you did something stupid with a null value"
If the Cache is empty you need to check that first
bool status1 = (bool)Cache["cache_req_head"];
should be
bool status1 = false;
if (Cache["cache_req_head"] != null)
{
status1 = (bool)Cache["cache_req_head"];
}
This is an effect of the fact that value types (like bool, int, etc) in c# can not be null. There is a wrapper, Nullable<T> with the shorthand T? that you can use if you want to allow null values for the value types.
You can cast your value to a bool? since that allows for null.
bool? status1 = (bool?)Cache["cache_req_head"];
You can then check status1 == null or status1.HasValue, to get the actual bool value you need to pick it out with status1.Value. If you pick status1.Value while status1 == null you will get a runtime exception like the one you just got.
Actually, the best way to check for whether a value exists or not in Cache is by doing:
//string is used as an example; you should put the type you expect
string variable = Cache["KEY"] as string;
if(variable!=null)
{
// do something
}
The reason why doing if(Cache["KEY"]!=null) myVariable=Cache["Key"]; is unsafe, is because the object stored in Cache["Key"] may be removed from Cache before you get a chance to assign it to myVariable and you end up thinking that myVariable holds a non-null value.
You obviously only setting one of the cache entries at a time. So unless you run the "setter" code 3 times with only 1 variable set to true, then you always going to have nulls returned.
null does not cast into bool because its a value type. Try using bool?
Since Cache[] returns an object, which is null if not set, then you're getting an exception trying to cast null into a bool.
You'd have to check if that key exists first, or you'd have to set each key to "false" as a default.