xzuluz
xzuluz

Reputation: 43

Excessive use of switch statements overhead

I have xml file with specific steps and actions that have to be performed on html controls:

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

There is a lot of controls that I will use and each control has several methods like Click, GetText, Exsists..

Currently I use switches to deal with it, but I heard that this is not a good practice. I have one switch to select specific control and also each control has switch to call specific method.

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;
        }

I don't have much experience with coding so I'm not sure whether it is good way to deal with this problem. Could you give me some suggestions how to do it better? Maybe there are some coding patterns which could be helpful here?

Upvotes: 4

Views: 282

Answers (5)

Rune FS
Rune FS

Reputation: 21742

you could create a class for each type of control you have

namespace SomeNamespace {
    class Button {
    }
    public void Click(){
    }
}

and then when you read the 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

Upvotes: 0

daryal
daryal

Reputation: 14919

if you can rename the names of the controls to match with class names, you may create instances via reflection;

string controlName = "System.Windows.Forms.Button";
Assembly assembly = typeof(Form).Assembly; 
Type type = assembly.GetType(controlName);
object controlObject = Activator.CreateInstance(type);

Also, you can invoke methods via reflection too;

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

Upvotes: -1

LukeHennerley
LukeHennerley

Reputation: 6434

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();
  }
}

Then return TableControl instead of Table and call/override Execute Command, which will call your specific command based on which type it is.

Create a different type which inherits your base control class, depending on what you want to do override the executecommand and call the action. Hopefully this helps?

Upvotes: 0

Chris Canal
Chris Canal

Reputation: 4865

I would suggest looking into creating a "Dispatch Table". You can see a C# example here: https://stackoverflow.com/questions/715457/how-do-you-implement-a-dispatch-table-in-your-language-of-choice

Upvotes: 2

dutzu
dutzu

Reputation: 3910

To make it more strongly typed (but also this introduces some overhead in that you must create classes) you could create classes for each control you want to obtain and serializer/deserialize those.

so instead of Item you would have for instance:

<Button action="Click" value="" />

They would all inherit from the same base class or implement the same interface so in the end you would obtain a deserialized IMyControls :)

and you could do a "switch case" based on the type they have.

Upvotes: 0

Related Questions