web-dev-qa-db-ja.com

オブジェクトが同じタイプかどうかを確認する

こんにちは、C#で同じ型のオブジェクトかどうかを確認する方法を知る必要があります。

シナリオ:

class Base_Data{}

class Person : Base_Data { }
class Phone  : Base_data { }

class AnotherClass
{
   public void CheckObject(Base_Data data)
   {
         if (data.Equals(Person.GetType()))
         { //<-- Visual Studio 2010 gives me error, says that I am using 'Person' is a type and not a variable.

        }
    }
}
46
slao

is演算子 を使用できます。

if (data is Person)
{
    // `data` is an instance of Person
}

別の可能性は、 as operator を使用することです。

var person = data as Person;
if (person != null)
{
    // safely use `person` here
}

または、C#7以降、上記の2つを組み合わせた is演算子のパターンマッチング形式 を使用します。

if (data is Person person)
{
    // `data` is an instance of Person,
    // and you can use it as such through `person`.
}
84
Darin Dimitrov

それはあなたが何を求めているかによって異なります。 isまたはasを使用すると(Darinの答えに示されているように)dataPersonまたはサブタイプのインスタンスを参照するかどうかがわかります。それが最も一般的な形式です(ただし、それを必要としないように設計できる場合は、さらに良いでしょう)-そして、それが必要な場合は、Darinの答えが使用するアプローチです。

ただし、exactの一致が必要な場合-dataPersonから派生したクラスのインスタンスを参照している場合、特定のアクションを実行したくない場合は、Person自体に対してのみ、次のようなものが必要です。

if (data.GetType() == typeof(Person))

これは比較的まれであり、この時点で設計に疑問を呈する価値は間違いありません。

25
Jon Skeet

これを一度に1ステップずつ修正しましょう。最初のステップは必須で、次の2つはオプションですが推奨されています。

最初の修正(必須)は、何らかのタイプのオブジェクトをSystem.Typeタイプのオブジェクトと比較していないことを確認します。

if (data.GetType().Equals(typeof(Person))) ...
//      ^^^^^^^^^^
//      add this to make sure you're comparing Type against Type, not
//      Base_Data against Type (which caused the type-check error)!

第二に、これを単純化するに:

if (data is Person) ... // this has (almost) the same meaning as the above;
                        // in your case, it's what you need.

番目、ifステートメントを完全に削除する!これは、ポリモーフィズム(または、より正確には、メソッドのオーバーライド)を使用することで行われます。次のように:

class Base_Data
{
    public virtual void Check() { ... }
}

class Person : Base_Data
{
    public override void Check()
    {
        ... // <-- do whatever you would have done inside the if block
    }
}

class AnotherClass
{
    public void CheckData(Base_Data data)
    {
         data.Check();
    }
}

ご覧のように、条件コードはBase_Dataクラスとその派生クラスCheckPersonメソッドにシフトされています。このような型チェックifステートメントはもう必要ありません!

9
stakx