Как безопасно использовать System.Object для `bool` в С#?
Я извлекаю значение 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;
Есть ли что-то подобное, что можно сделать для безопасного приведения объекта к типу значения без возможности InvalidCastException
если по какой-либо причине значение не является логическим?
Ответы
Ответ 1
Есть два варианта... с немного удивительной производительностью:
-
Избыточная проверка:
if (rawValue is bool)
{
bool x = (bool) rawValue;
...
}
-
Используя обнуляемый тип:
bool? x = rawValue as bool?;
if (x != null)
{
... // use x.Value
}
Удивительным моментом является то, что производительность второй формы намного хуже, чем первая.
В С# 7 вы можете использовать сопоставление с образцом для этого:
if (rawValue is bool value)
{
// Use value here
}
Обратите внимание, что вы все равно получите value
в области видимости (но не обязательно назначенное) после оператора if
.
Ответ 2
Вот так:
if (rawValue is bool) {
bool value = (bool)rawValue;
//Do something
} else {
//It not a bool
}
В отличие от ссылочных типов, нет быстрого способа применить к типу значения без двух отливок. (Или блок catch, что было бы хуже)
Ответ 3
bool value;
if(rawValue is bool)
value = (bool)rawValue;
else {
// something is not right...
Ответ 4
Вы можете передать его в bool?
с помощью ключевого слова as
и проверить свойство HasValue
.
Ответ 5
Вы не определили, что должно произойти, если rawValue не конвертируется в bool. Обычный выбор - вернуть false, null или сгенерировать исключение. Также существует возможность преобразования строкового представления rawValue в тип bool, например, Да/Нет, Истина/Ложь, 1/0 и т.д.
Я бы использовал 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
}
Ответ 6
При условии, что вам на самом деле не нужно хранить ссылку на rawValue
, здесь однострочник с использованием метода GetValueOrDefault()
структуры Nullable<T>
:
bool value = (map.GetValue(key) as bool?).GetValueOrDefault();
Вы также можете указать значение по умолчанию, используя метод перегрузки GetValueOrDefault(T)
.
Ответ 7
Я использовал эту проверку, прежде чем делать что-то с объектом
if(myCrazyObject.GetType().Equals(typeof(bool)))
{
//do smt with it
}
Ответ 8
Если целью является true, только если необработанный объект имеет логическое значение true', то однострочный (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'
Ответ 9
Вы также можете попробовать Convert.ToBoolean(rowValue);