Подтвердить что ты не робот

Как безопасно использовать 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 если по какой-либо причине значение не является логическим?

4b9b3361

Ответ 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);