我对基于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来控制,并且相信我很多东西都是不同的。所以有时我需要直接访问仪器类(重置寄存器,初始化或其他)。这就是我尝试做的事情。任何建议都非常受欢迎。
答案 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()方法。