tags:

views:

205

answers:

6

I am extracting a bool value from a (non-generic, hetrogeneous) collection.

The as operator may only be used with reference types, so it is not possible to do use as to try a safe-cast to bool:

// This does not work: "The as operator must be used with a reference type ('bool' is a value type)"
object rawValue = map.GetValue(key);
bool value = rawValue as bool;

Is there something similar that can be done so safely cast an object to a value type without possibility of an InvalidCastException if, for whatever reason, the value is not a boolean?

A: 

You can use typeof(rawvalue) is bool.

if typeof(rawvalue) is bool
{
    value = (bool)rawvalue;
}
SoMoS
No, you can't. You'll get a syntax error.
SLaks
No you can't - the `typeof` operator doesn't take a variable, it takes a type name.
Jon Skeet
I agree with SLaks and Jon. However, rawValue.GetType() == typeof(bool) would be possible but way too long in comparision to rawValue is bool.
Webleeuw
Unless `rawValue` is null.
SLaks
Okok, I just did a mistake trying to be the first one to answer the question. Hide your guns!!! :)
SoMoS
* Webleeuw hides his gun ;-)
Webleeuw
Thanks mate! :)
SoMoS
+5  A: 

Like this:

if (rawValue is bool) {
    bool value = (bool)rawValue;
    //Do something
} else {
    //It's not a bool
}

Unlike reference types, there's no fast way to try to cast to a value type without two casts. (Or a catch block, which would be worse)

SLaks
@SLaks: See mine and kalusbyskov's answers for alternatives to using two casts. Not that it really helps.
Jon Skeet
+4  A: 
bool value;
if(rawValue is bool)
  value = (bool)rawValue;
else {
  // something is not right...
Webleeuw
+2  A: 

You can cast it to a bool? with the as keyword and check the HasValue property.

klausbyskov
+11  A: 

There are two options... with slightly surprising performance:

  • Redundant checking:

    if (rawValue is bool)
    {
        bool x = (bool) rawValue;
        ...
    }
    
  • Using a nullable type:

    bool? x = rawValue as bool?;
    if (x != null)
    {
        ... // use x.Value
    }
    

The surprising part is that the performance of the second form is much worse than the first.

Jon Skeet
+3  A: 

You haven't defined what you want to have happen if rawValue is not convertible to bool. Common choices are to return false, null, or throw an exception. There's also the possibility of the string representation of rawValue to be convertible to a bool, such as Yes/No, True/False, 1/0, etc.

I would use bool.TryParse to do the conversion. This will succeed if rawValue is a bool or its ToString() returns "True".

bool result;
if (!bool.TryParse(rawValue.ToString(), out result))
{
    // you need to decide what to do in this case
}
Jamie Ide