60

簡単に言うと、Objectインスタンスとして渡される特定のタイプでタスクを実行するC#関数があります。クラスインスタンスが渡されると、すべて正常に機能します。ただし、オブジェクトがインターフェイスとして宣言されている場合は、具体的なクラスを見つけて、そのクラスタイプに対してアクションを実行したいと思います。

これは至る所にある悪い例です(間違ったプロパティケーシングなどで見事です):

public interface IA
{
    int a { get; set; }
}
public class B : IA
{
    public int a { get; set; }
    public int b { get; set; }
}
public class C : IA
{
    public int a { get; set; }
    public int c { get; set; }
}

// snip

IA myBObject = new B();
PerformAction(myBObject);

IA myCObject = new C();
PerformAction(myCObject);

// snip

void PerformAction(object myObject)
{
    Type objectType = myObject.GetType();   // Here is where I get typeof(IA)
    if ( objectType.IsInterface )
    {
        // I want to determine the actual Concrete Type, i.e. either B or C
        // objectType = DetermineConcreteType(objectType);
    }
    // snip - other actions on objectType
}

PerformActionのコードで、そのパラメーターに対してReflectionを使用し、それがIAのインスタンスであるだけでなく、Bのインスタンスであることを確認し、GetProperties()を介してプロパティ「b」を確認したいと思います。.GetType()を使用すると、IAのタイプを取得します-必要なものではありません。

PerformActionは、IAのインスタンスの基になる具象タイプをどのように判別できますか?

抽象クラスの使用を提案したくなる人もいるかもしれませんが、それは私の悪い例の限界にすぎません。変数は元々、インターフェースインスタンスとして宣言されます。

4

5 に答える 5

89
Type objectType = myObject.GetType();

あなたの例によれば、それでもあなたに具体的なタイプを与えるはずです。

于 2009-07-21T15:27:00.303 に答える
5

あなたがしているのは本当にベッドのデザインですが、反射を使う必要はなく、このようにチェックすることができます

void PerformAction(object myObject)
{
    B objectType = myObject as B;   // Here is where I get typeof(IA)
    if ( objectType != null )
    {
        //use objectType.b
    }
    else
    {
       //Same with A 
    }
    // snip - other actions on objectType
}
于 2009-07-21T15:26:20.260 に答える
5

私は悪いデザインについて同意しなければなりません。インターフェイスがある場合は、具体的な実装を気にせずに、いくつかの一般的な機能を利用する必要があるためです。あなたの例を考えると、PerformActionメソッドは実際にはインターフェースの一部である必要があるように思えます。

public interface IA
{
    int a { get; set; }
    void PerformAction();
}

public class B: IA
{
    public int a { get; set; }
    public int b { get; set; }

    public void PerformAction()
    {
        // perform action specific to B
    }
}

public class C : IA
{
    public int a { get; set; }
    public int c { get; set; }

    public void PerformAction()
    {
        // perform action specific to C
    }
}

void PerformActionOn(IA instance)
{
    if (instance == null) throw new ArgumentNullException("instance");

    instance.PerformAction();

    // Do some other common work...
}


B b = new B();
C c = new C();

PerformActionOn(b);
PerformActionOn(c);
于 2009-07-22T01:29:42.940 に答える
3

インターフェイスのインスタンスを持つことはできません。したがって、常に具象型を扱っているので、インターフェースを扱っているのか具象型を扱っているのかを判断することはできません。ですから、あなたの質問が意味をなすかどうかはわかりません。正確に何をしようとしているのですか、そしてその理由は何ですか?

于 2009-07-21T15:25:04.457 に答える
2

たぶんあなたはis演算子を探しています

void PerformAction(object myObject)
{
    if (myObject is B)
    {
        B myBObject = myObject as B;
        myBObject.b = 1;
    }

    if (myObject is C)
    {
        C myCObject = myObject as C;
        myCObject.c = 1;
    }

    // snip - other actions on objectType
}
于 2009-07-22T01:22:15.023 に答える