Cleanest syntax to logically AND multiple nullable boolean flags i

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Given several nullable boolean flags;

bool? l_flg_01 = true;
bool? l_flg_02 = false;
bool? l_flg_03 = true;
bool? l_result_flg = null;

I would have liked one of these syntax formats to work;

// if ( l_flg_01 && l_flg_02 && l_flg_03 ) // Line A
// if ( l_flg_01 & l_flg_02 & l_flg_03 ) // Line B
// if ( l_flg_01 &&? l_flg_02 &&? l_flg_03 ) // Line C
// if ( l_flg_01 &? l_flg_02 &? l_flg_03 ) // Line D
// if ( l_flg_01 AND l_flg_02 AND l_flg_03 ) // Line E

But I have to settle for casting (which looks messy) as below;

if ( (bool) l_flg_01 && (bool) l_flg_02 && (bool) l_flg_03 )
{
l_result_flg = true;
}
else
{
l_result_flg = false;
}

I thought 'lifted operators' would have worked for Line A or B.

My desired result, logically, is a null in any flag produces a false result.
My desired result, aesthetically, is a clean code line with no casting
baggage.

Do I have to write a custom operator for C# 2.0 nullable booleans,
(to get clean looking code) or am I missing something?

Thanks : shawnk

PS. I'm not worked about the logic, I would like to know about the aesthetics.
 
Since these are booleans, and you are defaulting a null to false (If I
am understanding this correctly) can you use a
System.Collections.BitArray instead?

John
 
Yes. However I wanted to get a feel for the use of nullable types in the
following general programming context.

You have a complex boolean state space whose cardinality is around a dozen
or so states. If the cardinality was around 32 to 64 I would move towards
bitmaps.

For cardinality of one order of magnitude (1 to 10) I would like to use
nullable boolean flags.

On the logic, defaulting Nulls to false is just and example for this post. I
can live with the default logical combinations from MS C# 2.0.

I'm just surprised that I can't string the nullable Bools together 'right
off the bat'.

Thats' really what I would like to know. Cant' we (us C# programmers) just
string the nullable bools together with & or && or something else?
 
This information is from the docs, perhaps it will help:

The bool? type

The bool? nullable type can contain three different values: true, false
and null. As such, the cannot be used in conditionals such as with if,
for, or while. For example, this code fails to compile with Compiler
Error CS0266:

bool? b = null;
if (b) // Error CS0266.
{
}

This is not allows because it is unclear what null means in the context
of a conditional. Nullable Booleans can be cast to a bool explicitly in
order to be used in a conditional, but if the object has a value if
null, InvalidOperationException will be thrown. It is therefore
important to check the HasValue property before casting to bool.
 
Excellent point and I am aware of exceptions thrown when NULL is accessed
(via the variables). I'm OK with that and can catch the exceptions (during
testing, etc).

The point is that C# 2.0 Nullable types was not designed 'clean' as a
general nullable 'flag' mechanism (My opinion of course).

Many programmers have 'rolled' their own nullable flags such as with Enums
(C++, C#). None are as general purpose as the current C# 2.0 implementation
(Kudos to the MS C# dev team), however they fell short on the utility of
nullable bool flags when you can't just say (Flg1 & Flg2 & Flg3) in an
expression. I've seen many good approaches from coders better than I and the
MS delivery falls short in its utility for nullable boolean logic (I still
like nullable types in C# but think it could have been done MUCH better). The
'MUCH' being reflective of the most important and utilitarian usage - a high
cardinality boolean space where you work in a small subset of that space in
any code block. This drops a lot of masking concerns with bitmapped
approaches.

So I"ll just put in a feature request to the C# compiler (VS Studio) to
change the logical combination syntax to one that (I think) is more
reflective of my own (limited and opinionated :-) experience with nullable
boolean logic.

Finally the 'lifted operators' should have covered the above behaviour (Flg1
& Flg2 & Flg3) as a compilable statement with runtime exceptions on null
values.

Since I am getting compile errors I figure that I'm missing something or
nullable types fell prey to the VS 2005 delivery schedule.
 
shawnk wrote:

Finally the 'lifted operators' should have covered the above behaviour (Flg1
& Flg2 & Flg3) as a compilable statement with runtime exceptions on null
values.

Since I am getting compile errors I figure that I'm missing something or
nullable types fell prey to the VS 2005 delivery schedule.

There is no lifted operator for && or || in the spec, but the &
operator compiles fine - it just works in a different way to what you
expect. (true & null) results in null, not false. (false & null results
in false though.) This is consistent with what I'd personally expect.

If you frequently need this, why not write a method like this:

static bool AllTrue (params bool?[] values)
{
foreach (bool? value in values)
{
if (!(value ?? false))
{
return false;
}
}
return true;
}

Jon
 
I tryed Jon's solution and it worked well. Thank you for an excellent solution.

I still will try to write a custom operator but the best solution is for me
to put in feature request for C# 3 so that we (programmers) can work with a
subset of complex boolean state space with a fairly clean expression.

This way we don't have to worry about bitmaps (the rest of state space) or
non-native (inherent in language spec) solutions.

Thanks Jon :-)

Jon Skeet said:
shawnk wrote:

Finally the 'lifted operators' should have covered the above behaviour (Flg1
& Flg2 & Flg3) as a compilable statement with runtime exceptions on null
values.

Since I am getting compile errors I figure that I'm missing something or
nullable types fell prey to the VS 2005 delivery schedule.

There is no lifted operator for && or || in the spec, but the &
operator compiles fine - it just works in a different way to what you
expect. (true & null) results in null, not false. (false & null results
in false though.) This is consistent with what I'd personally expect.

If you frequently need this, why not write a method like this:

static bool AllTrue (params bool?[] values)
{
foreach (bool? value in values)
{
if (!(value ?? false))
{
return false;
}
}
return true;
}

Jon
 
Back
Top