我如何找到实现接口的类

时间:2012-12-11 20:33:00

标签: c# winforms .net-4.0

我对基于C#的WinForms应用程序有一个架构问题。我真的希望有人能告诉我如何解决这个问题。

我有不同的类实现接口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();

有没有办法通过让接口变量可用来找出用于实现接口的类?

在真正的程序中,我有超过10个接口,这些接口由40多个类以完全不同的方式实现,所以我不想为我需要转换回原始类的所有时刻做任何switch语句。

------------------ UPDATE!

我想一些背景信息可以让我更容易解决问题,是的,我同意Ed S.这更像是关于我的设计的问题,但我非常愿意改变这一切。

我的科学应用支持40多种不同的科学仪器来测量半导体。温度,电流,电压,开关,你的名字。我定义了10个可供用户使用的功能:温度,电压,电流,开关等......这些功能都放在接口中; IT温度,电压等......

有些乐器可以做任何事情,有些乐器只能做部件。如果用户有一个支持的高质量温度测量设备,我们使用它来实现ITemperature,但是当他/她有一个昂贵的电压表,也可以测量温度时,我使用相同的仪器来测量温度和电压(所以仪器实现ITemperature和电压)。所有乐器都非常非常不同,几乎不可能制作一个抽象类来覆盖它们。有些需要通过Web界面进行控制,有些需要通过usb来控制,并且相信我很多东西都是不同的。所以有时我需要直接访问仪器类(重置寄存器,初始化或其他)。这就是我尝试做的事情。任何建议都非常受欢迎。

5 个答案:

答案 0 :(得分:2)

is关键字已记录为here,但从你的问题来看,你的架构中存在更大的问题。

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

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

答案 1 :(得分:1)

if (test1.GetType() == typeof(class2)) ...

或者:

var c = test1 as class2;
if (c != null) c.Class2Method();

答案 2 :(得分:1)

我认为你真正想要的是Duck Typing,而不是施法。 Casting几乎是一个编译时活动。您可以使用library或使用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;
    }        
}

您可以在运行时进行强制转换并在强制转换上调用方法,但它使用Reflection,并且速度非常快。请参阅here

答案 3 :(得分:1)

您不需要知道哪个类实现了接口。相反,您可以直接通过界面访问所需的功能。这就是接口的用途。

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

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

as关键字具有优于转换的优势,即对类型和转换的测试只是一个操作。否则,您必须使用is测试类型,然后使用()进行投射,再次对内部测试类型: - (

答案 4 :(得分:0)

使用您要测试的对象的GetType()方法。