web-dev-qa-db-ja.com

C#で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の可能性なしにオブジェクトを安全に値型にキャストするために実行できる類似の方法はありますか?

65
Daniel Fortunov

2つのオプションがあります...わずかに驚くべきパフォーマンスがあります:

  • 冗長チェック:

    if (rawValue is bool)
    {
        bool x = (bool) rawValue;
        ...
    }
    
  • Nullable型を使用する:

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

驚くべき部分は、 2番目の形式のパフォーマンスは最初の形式よりもはるかに悪い です。

C#7では、これにパターンマッチングを使用できます。

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

valueステートメントの後、スコープ内にifが存在することに注意してください(ただし、確実に割り当てられるわけではありません)。

112
Jon Skeet

このような:

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

参照型とは異なり、2つのキャストなしで値型にキャストしようとする高速な方法はありません。 (または、catchブロック、これはもっと悪いでしょう)

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

asキーワードを使用してbool?にキャストし、HasValueプロパティを確認できます。

RawValueがboolに変換できない場合に何が起こるかを定義していません。一般的な選択肢は、false、nullを返す、または例外をスローすることです。 Yes/No、True/False、1/0など、rawValueの文字列表現がブールに変換される可能性もあります。

変換にはbool.TryParseを使用します。 rawValueがブール値であるか、その文字列値が「True」または「False」の場合、これは成功します。

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

実際にrawValueへの参照を保持する必要がない場合は、 GetValueOrDefault()Nullable<T> 構造:

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

メソッドoverload GetValueOrDefault(T) を使用してデフォルト値を指定することもできます。

0
Nick W.

objectで何かを行う前にこのチェックを使用しました

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