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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1974922/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 22:20:04  来源:igfitidea点击:

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

c#.netcasting

提问by Daniel Fortunov

I am extracting a boolvalue from a (non-generic, heterogeneous) collection.

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

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

as运营商只能与引用类型使用,所以这是不可能做到的使用as尝试安全播到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 to safely cast an object to a value type without possibility of an InvalidCastExceptionif, for whatever reason, the value is not a boolean?

是否有类似的方法可以安全地将对象强制转换为值类型而不会出现InvalidCastExceptionif,无论出于何种原因,该值不是布尔值?

采纳答案by Jon Skeet

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
    }
    
  • 冗余检查:

    if (rawValue is bool)
    {
        bool x = (bool) rawValue;
        ...
    }
    
  • 使用可空类型:

    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.

令人惊讶的是,第二种形式性能比第一种差很多

In C# 7, you can use pattern matching for this:

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

if (rawValue is bool value)
{
    // Use value here
}

Note that you still end up with valuein scope (but not definitely assigned) after the ifstatement.

请注意,valueif语句之后,您仍然以in 范围(但未明确分配)结束。

回答by SLaks

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)

与引用类型不同,没有快速的方法可以尝试在没有两次强制转换的情况下强制转换为值类型。(或者一个catch块,这会更糟)

回答by Webleeuw

bool value;
if(rawValue is bool)
  value = (bool)rawValue;
else {
  // something is not right...

回答by Klaus Byskov Pedersen

You can cast it to a bool?with the askeyword and check the HasValueproperty.

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

回答by Jamie Ide

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.

如果 rawValue 不能转换为 bool,你还没有定义你想要发生的事情。常见的选择是返回 false、null 或抛出异常。还可以将 rawValue 的字符串表示形式转换为 bool,例如 Yes/No、True/False、1/0 等。

I would use bool.TryParse to do the conversion. This will succeed if rawValue is a bool or its string value is "True" or "False".

我会使用 bool.TryParse 进行转换。如果 rawValue 是 bool 或其字符串值是“True”或“False”,这将成功。

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

回答by user3934664

You can also try Convert.ToBoolean(rowValue);

你也可以试试 Convert.ToBoolean(rowValue);

回答by Nick W.

Providing you don't actually need to keep a reference to the rawValue, here's a one-liner using the GetValueOrDefault()method of the Nullable<T>structure:

如果您实际上不需要保留对 的引用rawValue,这里是使用结构GetValueOrDefault()方法的单行Nullable<T>

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

You can also specify a default value using the method overload GetValueOrDefault(T).

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

回答by Project Mayhem

I used this check before doing something with object

我在用对象做某事之前使用了这个检查

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

回答by dmitry

If the goal is to have trueonly if the raw object is boolean 'true' then one-liner (rawValue as bool?)?? falsewill do:

如果目标是有真正的只有原始对象是布尔“”,那么一行代码(rawValue as bool?)?? false就可以了:

object rawValue=null
(rawValue as bool?)?? false
false
rawValue="some string"
(rawValue as bool?)?? false
false
rawValue=true
(rawValue as bool?)?? false
true
rawValue="true"
(rawValue as bool?)?? false
false
rawValue=false
(rawValue as bool?)?? false
false
rawValue=""
(rawValue as bool?)?? false
false
rawValue=1
(rawValue as bool?)?? false
false
rawValue=new Dictionary<string,string>()
(rawValue as bool?)?? false
false`