过度使用switch语句会增加开销

4

我有一个XML文件,其中包含必须在HTML控件上执行的特定步骤和操作:

<Item control="Dropdown" action="Click" value=""/>
<Item control="Button" action="GetText" value=""/>
<Item control="Input" action="WriteText" value="Sample Text"/>

有很多控件我会使用,每个控件都有几种方法,比如ClickGetTextExsists等。

目前我使用开关来处理它,但我听说这不是一个好的做法。我有一个开关来选择特定的控件,每个控件也有一个开关来调用特定的方法。

switch (control)
            {
                case "button":
                    return new Button;
                case "table":
                    return new Table;
                (...)
            }

(...)


        switch (action)
        {
            case "click":
                this.Click();
                return true;
            case "gettext":
                this.GetText();
                return true;
            default:
                return false;
        }

我对编程没有太多经验,所以不确定这是否是解决问题的好方法。您能否给我一些建议如何更好地解决它?也许有一些编程模式可以在这里提供帮助吗?

5个回答

2

0
为了使其更强类型化(但这也会引入一些开销,因为您必须创建类),您可以为要获取的每个控件创建类并对其进行序列化/反序列化。
因此,您将拥有例如而不是Item:
<Button action="Click" value="" />

它们都将继承自同一基类或实现相同的接口,因此最终您将获得反序列化的IMyControls :)

并且您可以根据它们的类型进行“switch case”操作。


你不能序列化接口。 - default
我提到使用接口作为一种将它们全部捆绑在一个集合中,然后在 switch case 或其他地方分离处理它们的方法。 - dutzu
但是你会如何编写序列化器呢?XmlSerializer 不接受序列化接口,它需要一个实际的对象来进行序列化。 - default
@Default 你说得没错,但实际上他需要的是反序列化时间,因为问题只在于从现有的 XML 创建控件。而且,在序列化阶段它不会考虑接口,只有在反序列化阶段它才需要知道类型以便调用构造函数并创建一个实例并填充数据。 - dutzu

0
public class BaseControl
{
  public object Click(){ }
  public object GetText() { }
  public virtual object ExecuteCommand() { }
}
public class TableControl : BaseControl
{
  public override object ExecuteCommand()
  {
    //Do your method
    return base.GetText();
  }
}

然后返回TableControl而不是Table,并调用/覆盖Execute Command,根据其类型调用您的特定命令。

创建一个不同的类型,该类型继承您的基本控件类,具体取决于您想要执行的操作,覆盖executecommand并调用该操作。希望这可以帮助您?


0
你可以为每种控件创建一个类。
namespace SomeNamespace {
    class Button {
    }
    public void Click(){
    }
}

然后当您读取XML时

//assemblyName is the full name of the assembly holding your control classes
var type = System.GetType(assemblyName, "SomeNamespace." + control);
var control = Activator.CreateInstance(type); //requires a default constructor
type.GetMethod(methodName).Invoke(control); //methodName could be click

-1
如果您可以将控件的名称重命名为与类名匹配,那么您可以通过反射创建实例;
string controlName = "System.Windows.Forms.Button";
Assembly assembly = typeof(Form).Assembly; 
Type type = assembly.GetType(controlName);
object controlObject = Activator.CreateInstance(type);

此外,您也可以通过反射调用方法;

MethodInfo methodInfo = controlObject.GetType().GetMethod("Method Name");
methodInfo.Invoke(controlObject,null);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接