1

WinForms、C# ベースのアプリケーションのアーキテクチャに関する質問があります。誰かがこれを解決する方法を教えてくれることを本当に願っています。

インターフェイス ITest1 または ITest2 またはその両方を実装するさまざまなクラスがあります。

class1 : ITest1
class2 : ITest1, ITest2
class3 : ITest2

アプリケーションの開始時に、ITest1 と ITest2 のアプリケーションのライフタイプ全体 (class1、class2、または class3) で使用するクラスをアプリケーションに指示する構成ソースがあります。

ITest1 test1;
ITest2 test2;
switch (configresult)
{
    case "configuration1":
        test1 = new class1();
        test2 = new class2();
        break;
    case "configuration2":
        test1 = new class2();
        test2 = new class3();
        break;
    case "configuration3":  // This happens the most!
        test1 = new class2();
        test2 = (class2)test1;
        break;
}

ここで、実行時に特定のインターフェイスを実装するクラスを知りたいと思います。擬似コード:

if( test1 is implemented by class2 )
    ((class2)test1).Class2Method();

if( test2 is implemented by class1 )
    ((class1)test1).Class1Method();

インターフェイス変数を利用できるようにすることで、インターフェイスの実装に使用されるクラスを見つける方法はありますか?

実際のプログラムでは、40 以上のクラスによってまったく異なる方法で実装されている 10 を超えるインターフェイスがあるため、元のクラスにキャストバックする必要があるすべての瞬間に switch ステートメントを実行したくありません。

- - - - - - - - - アップデート!

いくつかの背景情報が問題を解決しやすくしていると思います。はい、それは私の設計に関する問題であるという Ed S. の意見に同意しますが、すべてを変更したいと思っています。

私の科学アプリケーションは、半導体を測定するために 40 以上の異なる科学機器をサポートしています。温度、電流、電圧、スイッチなど、何でも構いません。ユーザーが利用できる 10 の機能を定義しました: 温度、電圧、電流、スイッチングなど....これらはすべてインターフェイスに組み込まれています。ITemperature、IVoltage など...

すべてをこなせる楽器もあれば、パートだけをこなせる楽器もあります。ユーザーがサポートされている高品質の温度測定デバイスを持っている場合は、それを使用して ITemperature を実装しますが、温度も測定できる高価な電圧計を持っている場合は、同じ機器を使用して温度と電圧を測定します (したがって、機器は ITemperature を実装します)。および IVoltage)。すべてのインストゥルメントは非常に異なっており、1 つの抽象クラスですべてをカバーすることはほとんど不可能です。一部は Web インターフェイスで制御する必要があり、一部は USB で制御する必要があり、多くのことが異なると思います。そのため、インストルメント クラスに直接アクセスする必要がある場合があります (レジスタのリセット、初期化など)。これが私がやろうとしていることです。どんな提案でも大歓迎です。

4

5 に答える 5

2

ここisに文書化されたキーワードがありますが、あなたの質問からは、アーキテクチャに大きな問題があるように聞こえます。

if( test1 is class2 )
    ((class2)test1).Class2Method();

if( test2 is class1 )
    ((class1)test1).Class1Method();
于 2012-12-11T20:40:20.330 に答える
1
if (test1.GetType() == typeof(class2)) ...

または代わりに:

var c = test1 as class2;
if (c != null) c.Class2Method();
于 2012-12-11T20:36:12.627 に答える
1

どのクラスがインターフェイスを実装しているかを知る必要はありません。代わりに、インターフェイスを介して目的の機能に直接アクセスできます。それがインターフェースの目的です。

ITest1 test1 = obj as ITest1;
if (test1 != null) {
    test1.Test1InterfaceMethod();
}

ITest2 test2 = obj as ITest2;
if (test2 != null) {
    test2.Test2InterfaceMethod();
}

asキーワードには、型のテストとキャストが 1 つの操作にすぎないというキャストよりも利点があります。それ以外の場合は、型をテストしてからisキャストする必要があります()。内部で型を再度テストするもの:-(

于 2012-12-11T22:09:05.440 に答える
1

あなたが本当に探しているのは、キャストではなくダックタイピングだと思います。キャストはほとんどコンパイル時のアクティビティです。ライブラリまたは C# 4.0 のdynamicキーワードを使用して、ダック タイピングを実装できます。

public static dynamic Quack(dynamic duck)
{
    try
    {
        // bind method at run time and execute it
        return duck.Quack();
    }
    catch (RuntimeBinderException)
    {
        //throw if method call failed
        return null;
    }        
}

実行時にキャストし、キャスト時にメソッドを呼び出すことができますが、リフレクションを使用するため、それほど高速ではありません。ここを参照してください。

于 2012-12-11T21:54:48.603 に答える
0

テストするオブジェクトの GetType() メソッドを使用します。

于 2013-10-18T10:27:42.347 に答える