web-dev-qa-db-fra.com

Comment convertir en toute sécurité un System.Object en un `bool` en C #?

J'extrais une valeur bool d'une collection (non générique, hétérogène).

L'opérateur as ne peut être utilisé qu'avec des types de référence, il n'est donc pas possible d'utiliser as pour essayer un cast sécurisé vers 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;

Existe-t-il quelque chose de similaire qui peut être fait pour convertir un objet en un type de valeur en toute sécurité sans possibilité de InvalidCastException si, pour une raison quelconque, la valeur n'est pas un booléen?

65
Daniel Fortunov

Il y a deux options ... avec des performances légèrement surprenantes:

  • Vérification redondante:

    if (rawValue is bool)
    {
        bool x = (bool) rawValue;
        ...
    }
    
  • En utilisant un type nullable:

    bool? x = rawValue as bool?;
    if (x != null)
    {
        ... // use x.Value
    }
    

La partie surprenante est que le les performances de la deuxième forme sont bien pires que la première .

En C # 7, vous pouvez utiliser la correspondance de motifs pour cela:

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

Notez que vous vous retrouvez toujours avec value dans la portée (mais pas définitivement attribué) après l'instruction if.

112
Jon Skeet

Comme ça:

if (rawValue is bool) {
    bool value = (bool)rawValue;
    //Do something
} else {
    //It's not a bool
}

Contrairement aux types de référence, il n'y a aucun moyen rapide d'essayer de convertir un type de valeur sans deux transtypages. (Ou un bloc de capture, ce qui serait pire)

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

Vous pouvez le convertir en bool? avec le mot clé as et vérifiez la propriété HasValue.

4

Vous n'avez pas défini ce que vous voulez voir se produire si rawValue n'est pas convertible en bool. Les choix courants consistent à renvoyer false, null ou à lever une exception. Il y a aussi la possibilité que la représentation sous forme de chaîne de rawValue soit convertible en bool, comme Yes/No, True/False, 1/0, etc.

J'utiliserais bool.TryParse pour faire la conversion. Cela réussira si rawValue est un booléen ou si sa valeur de chaîne est "True" ou "False".

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

À condition que vous n'ayez pas réellement besoin de conserver une référence au rawValue, voici une ligne à l'aide de la méthode GetValueOrDefault() de la Nullable<T> structure:

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

Vous pouvez également spécifier une valeur par défaut à l'aide de la méthode overload GetValueOrDefault(T) .

0
Nick W.

J'ai utilisé cette vérification avant de faire quelque chose avec object

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