开发者

interpreting string of commands

say you have to interpret a sting of command arguments like AABBCDEEFF... and the idea is that each character represents a command for which you have to take some actions on the class, the ugly solution is to write a big switch-case but i dont want开发者_运维问答 to use that , can anybody suggest a more elegant solution ??


Create a map of methods like: map<char, func_ptr>, then fill it with your "actions":

act_map['A'] = &my_class::func_a
....

and

for each c in str
  arc_map[c]()

Real implementation depends of your language.

But if you have up to 5-10 actions than just use switch.


Make everything as simple as possible. Stay with the SWITCH.


Well my suggestion is switch, as the compiler will optimize it for you. How many potential characters are there that will occur?


For C#, In the more complex case a solution can be to implement and interface, or add attributes and use reflection to call the command or method.

OK, as an example i created some C# code

public class ExecuteSequence
    {
        Dictionary<string, Type> classes = new Dictionary<string, Type>();
        public void LoadClasses()
        {
            classes.Clear();
            //load all classes with attribute
            //this can be done at startup once, or on requested refresh
            foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
                foreach (Type type in assembly.GetTypes())
                    foreach (object attribute in type.GetCustomAttributes(typeof(MethodAttribute), true))
                        if (attribute.GetType() == typeof(MethodAttribute))
                            classes.Add(((MethodAttribute)attribute).MethodName, type);
        }

        public string Execute(string sequence)
        {
            string retVal = "";
            foreach (char c in sequence)
                if (classes.ContainsKey(c.ToString()))
                {
                    IMethod method = (IMethod)Activator.CreateInstance(classes[c.ToString()]);
                    retVal += method.Execute();
                }

            return retVal;
        }
    }

    public class MethodAttribute : Attribute
    {
        private readonly string m_MethodName;
        public MethodAttribute(string methodName)
        {
            m_MethodName = methodName;
        }
        public string MethodName
        {
            get { return m_MethodName; }
        }
    }
    public interface IMethod
    {
        string Execute();
    }

    [Method("A")]
    public class MethodA : IMethod
    {
        public string Execute()
        {
            return "FOO";
        }
    }

    [Method("B")]
    public class MethodB : IMethod
    {
        public string Execute()
        {
            return "BAR";
        }
    }

You can limit the list of initial assemblies scanned, but as mentioned, this should only load on startup.

Hope this helps.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜