checking if a nullable bool is null or not [duplicate] - c#

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
}

Related

Distinguish an explicitly nullable string type in C# [duplicate]

This question already has answers here:
How to use .NET reflection to check for nullable reference type
(6 answers)
Closed last year.
There are a lot of examples of string properties with "nullable" vs "non-nullable" declarations:
public MyClass {
public string NotNullable {get;set;}
public string? Nullable {get;set;}
}
This is even shown in the Microsoft C# official documentation on nullables as the primary example of nullable types.
This is made confusing by the fact that strings in C# can be null by default.
string myString = null; //100% valid, compile-able code
I have a script where I'm checking the types of properties in a class, to see if they are nullable. It's a long story why, but these nullable flags are put in a list and exported.
bool nullable = false;
if (classProperty.PropertyType.IsGenericType
&& classProperty.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
nullable = true;
}
This works for int?s, class references, DateTime? objects, basically anything other than string?, it can determine if it's an explicitly-declared nullable property or not.
Is there any way to determine if a property is string versus string?, and if not, why have (and laud in the documentation) a nullable string type for C#?
Also tried
An alternate method, comparing the PropertyType to a type derived directly:
modelProperty.PropertyType == typeof(int) //works
modelProperty.PropertyType == typeof(int?) //works
modelProperty.PropertyType == typeof(double) //works
modelProperty.PropertyType == typeof(double?) //works
modelProperty.PropertyType == typeof(string) //works
modelProperty.PropertyType == typeof(string?) //NOPE!
C# vomits an error about not being able to use the typeof operator on a nullable type when passed string? despite having literally just done so without issue for int? and double?. Also, modelProperty == typeof(string) is true whether the property was declared with either string or string?.
#Jesse got me pointed in the right direction. If anyone comes looking later, this is how I ended up checking and it seems to be working across the board:
if(modelProperty.PropertyType == typeof(string)
&& modelProperty.GetMethod?.CustomAttributes.Where(x => x.AttributeType.Name == "NullableContextAttribute").Count() == 0){
nullable = true;
}
Still glad to entertain any more succinct answers!

Comparing nullable ints

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
}

A neater way of handling bools in C# [duplicate]

This question already has answers here:
Best way to check for nullable bool in a condition expression (if ...) [closed]
(13 answers)
Closed 8 years ago.
Working with nullable bools in C# I find myself writing this pattern a lot
if(model.some_value == null || model.some_value == false)
{
// do things if some_value is not true
}
Is there a more compact way to express this statement? I can't use non-nullable bools because I can't change the model, and I can't do this
if(model.some_value != true)
{
// do things if some_value is not true
}
Because this will throw a null reference exception if model.some_value is null
One idea I had:
I could write an extension method for bools like String.IsNullOrEmpty - bool.IsNullOrFalse. This would be neat enough but I'm wondering if there's some more obvious way of doing this already?
Use a null-coalescing operator to handle cases where the value is null.
if(model.some_value ?? false != true)
{
// do things if some_value is not true
}
From msdn:
?? Operator (C# Reference)
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.
https://msdn.microsoft.com/en-us/library/ms173224.aspx
Alternatively, a switch would do it.
switch(model.some_value)
{
case false:
case null:
// do things if some_value is not true
break;
}

Querying a Nullable bool in C#

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;

ASP.NET C# Bool type casting

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.

Categories

Resources