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

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;
}

Related

C# nullable check optimization [duplicate]

This question already has answers here:
Deep null checking, is there a better way?
(16 answers)
Closed 5 years ago.
Can anyone tell me how do I optimize below code.
if (report != null &&
report.Breakdown != null &&
report.Breakdown.ContainsKey(reportName.ToString()) &&
report.Breakdown[reportName.ToString()].Result != null
)
As others have mentioned, you can use the ?. operator to combine some of your null checks. However, if you're after optimizing for performance, you should avoid the double dictionary lookup (ContainsKey and index access), going for a TryGetValue instead:
MyType match = null; // adjust type
if (report?.Breakdown?.TryGetValue(reportName.ToString(), out match) == true &&
match?.Result != null)
{
// ...
}
Ayman's answer is probably the best you can do for C# 6, for before that what you have there is pretty much the best you can do if all those objects are nullable.
The only way to optimize this further is to be checking if those objects are null before even calling the code, or better yet proofing your platform so this particular function shouldn't even be called in the first place if the values are null.
If you are just getting the value from from the dictionary however you can also simplify with the null coalescing operater '??'
Example:
MyDictionary['Key'] ?? "Default Value";
Thus if the Value at that entry is null you'll get the default instead.
So if this is just a fetch I'd just go
var foo =
report != null &&
report.Breakdown != null &&
report.Breakdown.ContainsKey(reportName.ToString()) ?
report.Breakdown[reportName.ToString()].Result ?? "Default" :
"Default";
But if you are actually doing things in the loop, then yeah you're pretty much at the best you can get there.
For C# 6 and newer, you can do it this way:
if (report?.Breakdown?.ContainsKey(reportName.ToString()) == true &&
report.Breakdown[reportName.ToString()].Result != null)
You can use null conditional operator but only on C# 6
if ( report?.Breakdown?.ContainsKey(reportName.ToString()) == true &&
report.Breakdown[reportName.ToString()].Result != null )
Can you try below? Also probably better to ship it to a method.
// unless report name is already a string
string reportNameString = reportName.ToString();
if ( report?.Breakdown?.ContainsKey(reportNameString) &&
report.Breakdown[reportNameString].Result != null )
{
// rest of the code
}

When text is null, text?.IndexOf(ch) != -1 is True?

Observation: If text is null, this method returns True. I expected False.
return text?.IndexOf('A') != -1;
When I reflect the above line using ILSpy (or inspect the IL), this is the generated code:
return text == null || text.IndexOf('A') != -1;
Here is what I really need to meet my expectation:
return text != null && text.IndexOf('A') != -1;
Question: Does someone have a good explanation about why the Null Conditional code generated the OR expression?
Full Sample at: https://dotnetfiddle.net/T1iI1c
The line above really involves two operations: a null-conditional operator method call, and a comparison. What happens if you store the result of the first operator as an intermediate variable?
int? intermediate = text?.IndexOf('A');
return intermediate != -1;
Clearly if text is null then intermediate will also be null. Comparing this with any integer value using != will return true.
From MSDN (emphasis mine):
When you perform comparisons with nullable types, if the value of one of the nullable types is null and the other is not, all comparisons evaluate to false except for != (not equal).
This code can be written using the null-conditional operator as long as you can use a different operator to ensure a comparison with null evaluates to false. In this case,
return text?.IndexOf('A') > -1;
will return the output you expected.

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()
}

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

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
}

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