[英]How do I safely cast a System.Object to a `bool` in C#?
I am extracting a bool
value from a (non-generic, heterogeneous) collection.我正在从(非通用的、异构的)集合中提取一个
bool
值。
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
: 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 InvalidCastException
if, for whatever reason, the value is not a boolean?如果出于某种原因,该值不是布尔值,是否可以执行类似的操作来安全地将对象转换为值类型而不会出现
InvalidCastException
?
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 .令人惊讶的是, 第二种形式的性能比第一种差很多。
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 value
in scope (but not definitely assigned) after the if
statement.请注意,在
if
语句之后,您仍然以作用域中的value
(但未明确分配)结束。
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块,这会更糟)
bool value;
if(rawValue is bool)
value = (bool)rawValue;
else {
// something is not right...
You haven't defined what you want to have happen if rawValue is not convertible to bool.如果 rawValue 不能转换为 bool,你还没有定义你想要发生的事情。 Common choices are to return false, null, or throw an exception.
常见的选择是返回 false、null 或抛出异常。 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,例如 Yes/No、True/False、1/0 等。
I would use bool.TryParse to do the conversion.我会使用 bool.TryParse 进行转换。 This will succeed if rawValue is a bool or its string value is "True" or "False".
如果 rawValue 是 bool 或其字符串值是“True”或“False”,这将成功。
bool result;
if (!bool.TryParse(rawValue as string, out result))
{
// you need to decide what to do in this case
}
You can cast it to a bool?
您可以将其转换为
bool?
with the as
keyword and check the HasValue
property.使用
as
关键字并检查HasValue
属性。
With C# 9 you can also simplify to:使用 C# 9,您还可以简化为:
if(rawValue is true)
{
//do stuff
}
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
的引用,这里是使用Nullable<T>
结构的GetValueOrDefault()
方法的单行:
bool value = (map.GetValue(key) as bool?).GetValueOrDefault();
You can also specify a default value using the method overload GetValueOrDefault(T)
.您还可以使用方法重载
GetValueOrDefault(T)
指定默认值。
I used this check before doing something with object我在用对象做某事之前使用了这个检查
if(myCrazyObject.GetType().Equals(typeof(bool)))
{
//do smt with it
}
If the goal is to have true only if the raw object is boolean ' true ' then one-liner (rawValue as bool?)?? false
如果目标是有真正只有在生对象是布尔“真”,然后一行代码
(rawValue as bool?)?? false
(rawValue as bool?)?? false
will 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`
bool value = (rawValue is null) ? false : (bool)rawValue.value;
如果 rawValue 为null
则 value 将为false
,否则 value 将接收正确的布尔值。
你也可以试试 Convert.ToBoolean(rowValue);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.