最近工作中遇到这样一个情况:
公司有各种型号的仪器仪表,他们都可以通过串口收发命令来实现某些相同的功能。例如读取某个数据,但是不同的型号收发的命令是不同的,例如A型号是仪器自动定时往串口发数据的,而B型号是需要上位机发命令过去后,仪器才会返回数据的。
于是,上位机会给用户一个下来菜单,当用户选中不同型号的产品的时候,收发的命令会相应调整。这时候一种方式是在主流程中加入Switch语句或if语句。 但这会导致主流程结构混乱,也不符合面向对象的思路。于是,决定写个接口,主流程中使用统一的方法获取数据。
类似这样:
public interface MyInterface{
void Method();
}
public class Class1:MyInterface{
public void Method(){
xxxxxxxxx;
}
}
public class Class2:MyInterface{
public void Method(){
yyyyyyyyyy;
}
}
//主流程中
MyInterface myInterface;
if(xx){
myInterface = new Class1(); //这里还是需要把所有的类名列在主流程里,当添加型号的时候,还是需要修改这个部分
}else{
myInterface = new Class2();
}
myInterface.Method();
经过两天研究,通过System.Reflection.Assembly可以通过字符串实现新建对象(类似java的Class.forName)。未了描述详细点,这里分布写,实际代码可以写在一行上
Assembly assembly = Assembly.GetExecutingAssembly(); //获取包含当前代码的程序集
object o = assembly.CreateInstance("完整类名"); //这里所述的完整类名指的是包括名称空间,即:名称空间.类名
MyInterface myInterface = o as MyInterface; //强制类型转换
myInterface.Method();
PS:此方式仅限于要导入的类与当前代码在同一个程序集中时,当不在同一个程序集中,就需要使用Load载入Assembly.Load("MyDll")来获取Assembly对象。