views:

314

answers:

6

Is it possible to use together any way operator ?? and operator && in next case:

bool? Any
{
   get
   {
      var any = this.ViewState["any"] as bool?;
      return any.HasValue ? any.Value && this.SomeBool : any;
   }
}

This means next:

  • if any is null then this.Any.HasValue return false
  • if any has value, then it returns value considering another boolean property, i.e. Any && SomeBool
+3  A: 

Is this what you mean?

bool? Any 
{ 
   get 
   { 
      return ((this.ViewState["any"] as bool?) ?? false) && this.SomeBool;
   } 
} 

I've left the return value as bool? but it looks like it could be changed to just bool.

This was tested like this:

class Program
{
    private static readonly Dictionary<string, object> ViewState = new Dictionary<string, object>();
    private static bool SomeBool;

    static void Main(string[] args)
    {
        ViewState["any"] = (bool?)null; SomeBool = true; Console.WriteLine(Any);
        ViewState["any"] = (bool?)false; SomeBool = true; Console.WriteLine(Any);
        ViewState["any"] = (bool?)true; SomeBool = true; Console.WriteLine(Any);
        ViewState["any"] = (bool?)null; SomeBool = false; Console.WriteLine(Any);
        ViewState["any"] = (bool?)false; SomeBool = false; Console.WriteLine(Any);
        ViewState["any"] = (bool?)true; SomeBool = false; Console.WriteLine(Any);
        Console.ReadLine();
    }

    static bool? Any
    {
        get
        {
            return ((ViewState["any"] as bool?) ?? false) && SomeBool;
        }
    }
}

which returns

False
False
True
False
False
False

The behaviour here is not quite the same as the original as null should be returned for test cases 1 and 4 to be identical. But maybe that behaviour isn't required?

Daniel Renshaw
Unfortunately, no. `result as bool?` has always `HasValue = true`. doesn't it?
abatishchev
You're right Henk, the behaviour is different
Daniel Renshaw
He wants to return null if any is null AND the two other conditions are false. So, he wants TRUE, FALSE and NULL
Atømix
Daniel, thank you very much for your detailed answer! But unfortunately we talk about different behaviors - I need to keep return value being `Nullable<bool>` so checking to `HasValue` would have a sense
abatishchev
Daniel Renshaw
A: 

This has the behavior you describe:

return (any ?? false) && this.SomeBool

Chris
As Daniel Renshaw's answer, yours one also always has value - `true` or `false`, never `null`
abatishchev
+3  A: 

I think what you're trying to do is this:

return any ?? (any.Value && this.SomeBool) ? true : new Nullable<bool>();

However, I think in cases like this, it's probably more clear to use an if block:

if ( !any.HasValue )
  return (any.Value && this.SomeBool) ? true : any;
else 
  return any;

If any is null, then you want to return true or null, right?

Atømix
+1  A: 

thing is, you don't really want to use the ?? operator. Its meant to make it easy to avoid nulls, you actually want to keep nulls.

Keith Nicholas
+3  A: 

I'm wondering why nobody has suggested this so far:

bool? any = this.ViewState["any"] as bool?;
return any & this.SomeBool;

This returns

  • null if any is null, no matter what the value of this.SomeBool is;
  • true if both any and this.SomeBool are true; and
  • false if any is not null, and this.SomeBool is false.
dtb
code looks good, description is wrong though (how can you return both `null` and `false` at the same time, yet that's what your rules say would happen for `any == null` and `this.SomeBool == false`.
Ben Voigt
@Henk Holterman: Why are the operands `'bool' and 'bool?'` and not `'bool?' and 'bool'`!? The left operand is clearly of type `bool?` as I declared it as such.
dtb
@Henk Holterman: Yes, but I made a typo when copying it to my answer :-( Fixed it now. My test program: `bool? x = null; bool y = true; bool? z = x `
dtb
Your code can be rewritten as: `return this.ViewState["any"] as bool? `, right?
abatishchev
@abatishchev: I think so. May need some `(`/`)`.
dtb
Robert Paulson
+3  A: 

The Null Coalescing operator isn't going to work for how you've structured the logic for your method. Sure you could force it in there, but it's going to look ugly and just confuse whomever reads it.

I found the original code hard to read and understand, so refactored and removed the ternary operator to reveal intentions.

bool? any = this.ViewState["any"] as bool?;

if (any == null)
    return null;

return any.Value && this.SomeBool;

Null coalescing is just nice shorthand and should be used judiciously

Person contact = Mother ?? Father ?? FirstSibling;

Is more intention revealing, and easier to read + maintain than:

Person contact = Mother;
if (contact == null)
    contact = Father;
if (contact == null)
    contact = FirstSibling;
Robert Paulson