关于.net:如何在C#中将System.Object安全地转换为`bool`?

How do I safely cast a System.Object to a `bool` in C#?

我正在从(非通用、异构)集合中提取bool值。

as运算符只能用于引用类型,因此不可能使用as尝试对bool进行安全强制转换:

1
2
3
// 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;

如果由于任何原因,该值不是布尔值,是否可以执行类似的操作来安全地将对象强制转换为值类型而不可能是InvalidCastException


有两种选择…性能稍显惊人:

  • 冗余检查:

    1
    2
    3
    4
    5
    if (rawValue is bool)
    {
        bool x = (bool) rawValue;
        ...
    }
  • 使用可为空的类型:

    1
    2
    3
    4
    5
    bool? x = rawValue as bool?;
    if (x != null)
    {
        ... // use x.Value
    }

令人惊讶的是,第二种形式的表现比第一种形式差得多。

在C 7中,您可以使用模式匹配:

1
2
3
4
if (rawValue is bool value)
{
    // Use value here
}

注意,在if语句之后,您仍然会在作用域(但没有明确指定)中使用value


这样地:

1
2
3
4
5
6
if (rawValue is bool) {
    bool value = (bool)rawValue;
    //Do something
} else {
    //It's not a bool
}

与引用类型不同的是,没有两个强制转换,就无法快速尝试强制转换为值类型。(或者是一个更糟的拦网)


1
2
3
4
5
bool value;
if(rawValue is bool)
  value = (bool)rawValue;
else {
  // something is not right...

如果rawvalue不能转换为bool,您还没有定义要发生什么。常见的选择是返回false、null或引发异常。也有可能将rawvalue的字符串表示转换为bool,例如yes/no、true/false、1/0等。

我会用bool.triparse进行转换。如果rawvalue是bool或其字符串值是"true"或"false",则此操作将成功。

1
2
3
4
5
bool result;
if (!bool.TryParse(rawValue as string, out result))
{
    // you need to decide what to do in this case
}

您可以使用as关键字将其强制转换为bool?并检查HasValue属性。


我在处理对象之前用过这张支票

1
2
3
4
if(myCrazyObject.GetType().Equals(typeof(bool)))
{
   //do smt with it
}


如果您实际上不需要保留对rawValue的引用,这里有一个使用Nullable结构的GetValueOrDefault()方法的一行程序:

1
bool value = (map.GetValue(key) as bool?).GetValueOrDefault();

您还可以使用方法重载GetValueOrDefault(T)来指定默认值。


您还可以尝试convert.toboolean(rowvalue);