2016-06-26 3 views
3

私はこのようないくつかのチェックを行う必要があります。クラスがC#で変数として与えられた型のインスタンスであるかどうかをチェックする方法は?

if(thisInstance is ThatClass || thisInstance is ThatOtherClass) 

私は実際にこれらの多くを行うために必要とされることはありませんので、それは上記のように、私は単にそれを書くことができますが、私は思いますそれでもやはりもっときちんとしたやり方でこれをやることを好む。このように:

Type[] arrayOfClasses = new Type[] { typeof(ThatClass), typeof(ThatOtherClass))} 
if(isOfAnyType(thisInstance, arrayOfClasses)) 

しかし、私はそれを動作させることはできません。

thisInstance.GetType() 

typeof(ThatClass) 

の文字列表現が同じになるにもかかわらず、いくつかの理由について、

thisInstance.GetType().IsInstanceOfType(type) 

はまだ常にfalseになります。

違いがある場合、これはUnityプロジェクトです。したがって、同等の項目(thisInstance.GetType()。GetType()など)に対してさらにGetType()を呼び出すと、結果は常にSystem.MonoTypeになります。この場合、IsInstanceOfTypeは常にtrueを返しますが、もちろん役に立ちません。

比較が失敗する理由、またはそれを動作させる方法については、または、私はただ単にあきらめて、必要に応じて "ThisInstance is ThatClass"を使用するだけですか?

+1

元のコードは、どのような意味でも「不揃い」とはみなされません。それは非常に簡単なようです。なぜあなたは、言語の演算子を使用することができます反射を使用する?より良い質問は、「私のコードを再構成して、チェックが不要なのですか?」です。 –

+0

まあ、これらの2つのクラスだけでは、特に不安定ではありませんが、設定が容易ではなく、より多くのクラスでは私の見解ではちょっと奇抜です。 – Jeffed

+0

確かに、問題は次のようなものです:なぜあなたは物事のタイプのランタイムチェックをたくさんしなければならないプログラムを持っていますか?ランタイムチェックの結果である複雑でないコードを書き留めようとするのではなく、それらを完全に排除しようとします。 –

答えて

1

あなたはisSubclassを使用することができます。

thisInstance.GetType().IsSubclassOf(typeof(ThatClass)) 
+1

提案していただきありがとうございます。クラスがまったく同じ型のクラスでも動作しません。 – Jeffed

1

あなたは、このメソッドを使用することができます動作するようにご希望の方法を取得するには:

public static bool IsOfAnyType(object obj, Type[] types) 
{ 
    return types.Any(type => type.IsInstanceOfType(obj)); 
} 

あなたはLINQのを使用できない場合は、このようなメソッドを書くことができます:

public static bool IsOfAnyType(object obj, Type[] types) 
{ 
    foreach (var type in types) 
    { 
     if (type.IsInstanceOfType(obj)) 
      return true; 
    } 
    return false; 
} 

これをテストするために、私はこのコードを使用しました

Type[] typesToCheck = { typeof(ThatClass), typeof(ThatOtherClass) }; 

ThatClass input1 = new ThatClass(); 
ThatOtherClass input2 = new ThatOtherClass(); 

if (IsOfAnyType(input1, typesToCheck)) 
    Console.WriteLine("Hello world from " + input1.GetType()); 
if (IsOfAnyType(input2, typesToCheck)) 
    Console.WriteLine("Hello world from " + input2.GetType()); 
+3

'obj.GetType()== type'は' is'と同じ振る舞いをしません。あなたは 'type.IsAssignableFrom(obj.GetType())'を使う必要があります。 –

+0

@ScottChamberlain素晴らしい提案です。 。ありがとう! –

+1

クール、ありがとう! Linqの実装は信じられないほどコンパクトです。以前はいくつかの統合のために使ってきましたが、実際にはより一般的な方法で使用する必要があります。実際には "IsInstanceOfType"が実際に行っていることですが、私の見解では直感的ではありません。私は「猫は動物の型です」と真実になりますが、「動物は型の猫のインスタンスです」と誤っていると思います。しかし、明らかにドキュメントによれば、「現在の型が継承階層にある」限り、それは本当です。したがって、あなたの提案は機能します! – Jeffed

3

このようなものを使用できます。このメソッドは、汎用オブジェクトが配列内のいずれかのタイプであるかどうかをチェックし、boolを返します。

public static bool IsOfAnyType<T>(T obj, Type[] types) 
    { 
     bool isOfAnyType = false; 

     for (int i = 0; i < classes.Length; i++) 
     { 
      if (types[i].IsAssignableFrom (obj.GetType())) 
      { 
       isOfAnyType = true; 
       break; 
      } 
     } 
     return isOfAnyType; 
     }  
+0

ジェネリックの必要性はなぜですか?すべてがすでに「オブジェクト」から派生しています。ジェネリックの使用は、不必要なオーバーヘッドのように思えます。 –

+0

@MattRowland - 私はその反対を主張するでしょう。 'object object'を使うと暗黙的なboxingとunboxingが起こりますが、ジェネリックスを使うとオブジェクトはT型のままです。実際には、オブジェクトを使うかどうかにかかわらず、同じマシンコードに変換されると思います。 – pijemcolu

+0

ありがとう!ジェネリックの有無にかかわらず、IsAssignableFromは動作するようです!奇妙なことは、私はすでにそれをテストしていると思っていたと思うかもしれませんが、おそらく私は物事を間違った方法で考え、間違った場所でテストする2つのタイプを持っていたと思います。だからいずれにせよ、問題は解決した! – Jeffed

関連する問題