比使用太多开关箱更好的解决方案



我有这个switch case来识别Excel中的值,并检查要根据DemoName中的值传递调用哪个函数,但我需要一个比这更好的解决方案:

public void SelectDemoAccount(string dataKeyname, string sheetName)
{
var Demo = new Demoing(DriverHelper.GetDriver);
var ud = ExcelDataHelper.GetTestData(dataKeyname, sheetName);
String DemoName = ud.DemoName;
switch (DemoName)
{
case "Abc":
Demo.ClickAbc();
break;
case "Def":
Demo.ClickDef();
break;
case "Ghi":
Demo.ClickGhi();
break;
case "Dsa":
Demo.ClickDsa();
break;
case "Qwe":
Demo.ClickQwe();
break;
case "Zxc":
Demo.ClickZxc();
break;
case "Hjk":
Demo.ClickHjk();
break;
case "Fgh":
Demo.ClickFgh();
break;
case "Cxz":
Demo.ClickCxz();
break;
case "Nmq":
Demo.ClickNmq();
break;
case "Atb":
Demo.ClickAtb();
break;
case "Smt":
Demo.ClickSmt();
break;
case "Mdt":
Demo.ClickMdt();
break;
case "Ldt":
Demo.ClickLdt();
break;
case "Cdt":
Demo.ClickCdt();
break;
case "Hdt":
Demo.ClickHdt();
break;
}    
}

您可以创建一个Dictionary,其中Key是您在当前开关代码中使用的字符串,Value是要从demo变量执行的方法。

var Demo = new Demoing(DriverHelper.GetDriver);
Dictionary<string, Action> demoMethods = new Dictionary<string, Action>();
demoMethods.Add("Abc", Demo.ClickAbc);
... add the other keyvalue pairs here

现在,当你需要调用这个方法时,只需使用

var ud = ExcelDataHelper.GetTestData(dataKeyname, sheetName);
String DemoName = ud.DemoName;
demoMethods[DemoName].Invoke();

这假设你总是使用相同的Demo实例,否则,如果调用的代码不是静态的,但需要在Demoing类的实例上执行,你需要在Demo类中有一组静态方法。每个静态方法接收一个Demoing类的实例,以便与底层方法一起工作。

public class Demoing
{
public static void ClickAbc(Demoing current)
{
current.DoSomething();
.... whatever ....
}
}

现在你可以使用不同的Action值

来准备你的字典了
Dictionary<string, Action<Demo>> demoMethods = new Dictionary<string, Action<Demo>>();
demoMethods.Add("Abc", Demoing.ClickAbc);

当你需要用一个特定的实例调用这个方法时,你可以写

var Demo = new Demoing(DriverHelper.GetDriver);
var ud = ExcelDataHelper.GetTestData(dataKeyname, sheetName);
String DemoName = ud.DemoName;
demoMethods[DemoName].Invoke(Demo);

最后,还有另一种方法可以使用字典而不使用静态方法,并将所有内容封装在Demoing类中。这个想法来自蒂姆·施梅尔特(Tim Schmelter)已经删除的一个答案。
这里的字典位于演示类的内部,并且提供了一个公共方法来访问字典操作,如:

public class Demoing
{
private Dictionary<string, Action> nameActions;

private Demoing()
{
InitNameActions();
}
private void InitNameActions()
{
nameActions = new Dictionary<string, System.Action>(StringComparer.OrdinalIgnoreCase)
{
{"Abc", ClickAbc},
// ...
}
}
public Action GetAction(string name){
return nameActions.TryGetValue(name, out Action action) ? action : null;
}
}

,调用是下面的

var demo = new Demoing(DriverHelper.GetDriver);
String demoName = ud.DemoName;
Action action = demo.GetAction(demoName);
action?.Invoke();
从封装的角度来看,这种方式更好。但是请记住,现在每个Demoing类型的对象都有自己的Dictionary,如果你周围有很多Demoing对象,这可能不是内存占用的最佳选择。

另一种方法是使用反射,它较慢,但它工作,它需要更少的代码行:

var Demo = new Demoing(DriverHelper.GetDriver);
var ud = ExcelDataHelper.GetTestData(dataKeyname, sheetName);
var mi = typeof(Demoing).GetMethod("Click" + ud.DemoName);
mi.Invoke(Demo);

另一种方法是创建键、值对的映射。在所有键中找到DemoName。如果DemoName是键,则执行value函数。

最新更新