2009-07-21 3 views
36

長い話を簡単にまとめると、Objectインスタンスとして渡される特定のタイプのタスクを実行するC#関数があります。クラスインスタンスが渡されたときは、すべて正常に動作します。しかし、オブジェクトがインターフェイスとして宣言されたとき、具体的なクラスを見つけて、そのクラスタイプに対してアクションを実行したいと思っています。私はPerformActionのコードは、それはパラメータがありますに対してリフレクションを使用して、それがIAのインスタンスだけではないことを見てみたいと思いインターフェイスインスタンスの背後にあるコンクリートタイプを見つける

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 
} 

:ここ

は(間違ったプロパティケーシングなどと輝く)ユビキタス悪い例です。それはBのインスタンスであり、GetProperties()を介してプロパティ "b"を参照するということです。私が.GetType()を使用すると、IAのタイプが得られます。

PerformActionはIAのインスタンスの基礎となる具体的なタイプをどのように決定できますか?

抽象クラスを使用することを示唆したくなるかもしれませんが、それは私の悪い例の単なる制限です。この変数はもともとはインタフェースインスタンスとして宣言されます。

+7

これは悪いデザインのようです。特定の具体的な型についてメソッドに知らせるのではなく、多態性を使用する必要があります。後で追加するとどうなりますか? –

+4

それはインターフェイスの目的を破るものではありませんか?インタフェースを実装している限り、具体的な型が何であるか気にする必要はありません。 –

+2

+1ジョンとクリス、それだけでなく、それは悪いデザインですが、質問は意味をなさない。 –

答えて

56
Type objectType = myObject.GetType(); 

のようにそれを確認することができますリフレクションを使用する必要はありません。

+2

はい、 "myObject.GetType()"を呼び出すと、インターフェイスタイプが返されません。 – TcKs

+0

'PerfomAction'のパラメータは' object'ですが、できませんでした。例えばIA.getType()です。 –

2

インターフェイスのインスタンスを持つことはできません。だから、あなたが常に具体的な型を扱うので、あなたがインタフェースか具体的な型を扱っているかどうかを判断することはできません。だから私はあなたが疑問に思っているかどうかわからない。あなたは正確に何をしようとしていますか、なぜですか?何をやっている

+2

+1正確には、実際に彼の例は正常に動作します。 –

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 
} 
+2

まだコンクリートタイプに依存しているので、これはかなり悪いデザインです。これは主に最初のインターフェースを持つという目的を大きく破っています... – jrista

+0

私の頭の中で叫んでいます: "LSP、ISP、DIP !!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!! " – Sebastien

0

たぶん、あなたは私が悪いデザインについて同意する必要がis operator

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 
} 
+0

あなたはそれを2回キャストしています。すぐに 'as'演算子を使って、後でnullをチェックしてください – nawfal

4

を探しています。インターフェイスを持っている場合は、具体的な実装が何であるかを気にせずに共通の機能を利用する必要があるからです。たとえば、あなたは、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); 
関連する問題