【问题标题】:How to run a string method?如何运行字符串方法?
【发布时间】:2013-03-13 06:44:38
【问题描述】:

这就是我想要的:

static void A(string s)
{
    //Code Here...
}
static void B(string s)
{
    //Code Here...
}
static void C(string s)
{
    //Code Here...
}
static void Main(string[] args)
{
      string temp = Console.ReadLine();
      string[] s = temp.Split(' ');
      if (s[0] == "A")
          A(s[1]);
      if (s[0] == "B")
          B(s[1]);
      if (s[0] == "C")
          C(s[1]);
}

但是当我有很多方法时,它并不能很好地工作......

还有其他方法吗?

【问题讨论】:

  • 当你有很多方法时为什么它不起作用?有什么问题?
  • 至少可以使用一种方法吗?给我你的输入格式
  • Ferpega - 每次要运行方法时都必须编写 20 个 if 语句,这真的很烦人

标签: c# string methods


【解决方案1】:

你可以这样写。

private static void Main(string[] args)
    {
        InitializeFunctions();

        string temp = Console.ReadLine();
        string[] s = temp.Split(' ');

        _functions[s[0]].Invoke(s[1]);
    }

    private static void InitializeFunctions()
    {
        _functions.Add("A",A);
        _functions.Add("B",B);
        _functions.Add("C",C);
    }

    private static Dictionary<string, Func> _functions = new Dictionary<string, Func>();

    public delegate void Func(string process);

    static void A(string s)
    {
        //Code Here...
    }
    static void B(string s)
    {
        //Code Here...
    }
    static void C(string s)
    {
        //Code Here...
    }

如果您将拥有具有相同签名的新方法,只需将其添加到 InitializeFunctions 方法中的 _functions 字典即可。

【讨论】:

    【解决方案2】:

    有时您可以使用DictionaryActions 将字符串映射到方法:

    using System;
    using System.Collections.Generic;
    
    namespace Demo
    {
        internal class Program
        {
            private static void Main(string[] args)
            {
                _actions = new Dictionary<string, Action<string>>();
    
                _actions["A"] = A;
                _actions["B"] = B;
                _actions["C"] = C;
    
                string[] s = Console.ReadLine().Split(' ');
    
                if (!processArg(s[0], s[1]))
                {
                    // Argument wasn't in the list. Do error handling.
                }
            }
    
            static bool processArg(string name, string value)
            {
                Action<string> action;
    
                if (_actions.TryGetValue(name, out action))
                {
                    action(value);
                    return true;
                }
    
                return false;
            }
    
            static void A(string s)
            {
                Console.WriteLine("A: " + s);
            }
    
            static void B(string s)
            {
                Console.WriteLine("B: " + s);
            }
    
            static void C(string s)
            {
                Console.WriteLine("C: " + s);
            }
    
            private static Dictionary<string, Action<string>> _actions;
        }
    }
    

    【讨论】:

      【解决方案3】:

      你想用的是这样的。

      typedef void (*FuncType)();
      
      std::map<char, FuncType> Fonctions;
      
      Fonctions['A'] = &FonctionA;
      ...
      Fonctions['Z'] = &FonctionZ;
      
      Fonctions[s[0]](s[1]);
      

      您还必须检查Function[s[0]] 是否已定义。

      【讨论】:

      • @keyboardP 我没有意识到这一点。包含函数指针的数组也存在于 C# 中。
      【解决方案4】:

      如果没有更多关于您要做什么的详细信息,一个基本的替代方法可能是使用一种方法并使用 switch 语句。

      static void PerformAction(string method, string cInput)
      {
          switch(method)
          {
             case "A":                   
                    //code
                    //something with cInput
                    break;
             case "B":
                    //code
                    break;
             //..
             default:
                    //default action code                  
          }    
      
      }
      

      然后这样称呼它

      string temp = Console.ReadLine();
      string[] s = temp.Split(' ');
      PerformAction(s[0],s[1]);
      

      【讨论】:

        【解决方案5】:

        有两种方法可以处理这个特殊问题:

        1. 使用 switch 语句
        2. 使用反射

        切换语句

        在这种情况下,您可以像这样组织代码:

        switch (s[0])
        {
            case "A":
                A(s(1));
                break;
        
            case "B":
                B(s(1));
                break;
        
            // and so on
        }
        

        ** 使用反射 **

        如果要通过名称调用方法,从字符串中获取名称,则必须使用反射:

        MethodInfo method = typeof(Program).GetMethod(s(0)); // guessing "Program" here
        if (method != null)
            method.Invoke(null, new object[] { s(1) });
        

        但是,我不会使用来自用户的输入来执行此操作,这就像 SQL 注入攻击,只会更糟。

        【讨论】:

          【解决方案6】:

          试试这个:

              static void A(string s)
              {
                  //Code Here...
              }
              static void B(string s)
              {
                  //Code Here...
              }
              static void C(string s)
              {
                  //Code Here...
              }
              public struct ActionStruct {
                public string String;
                public Action<string> Action;
                public ActionStruct(string s, Action<string> a) : this() {
                  String = s; Action = a;
                }
              }
              void Main(string[] args) {
                var actions = new List<ActionStruct>() {
                  new ActionStruct("A", s => A(s)),
                  new ActionStruct("B", s => B(s)),
                  new ActionStruct("C", s => C(s))
                };
                var action = actions.Where(a=>a.String == args[0]).FirstOrDefault();
                if (action.String!= "") action.Action(args[1]);
              }
          

          【讨论】:

            【解决方案7】:

            此代码适用于所有方法,可能是您的输入不正确或您想要执行多个方法。

            例如:

            如果您正在从控制台读取以下行,那么

            A Abcdefg
            

            拆分后 s[0] 将是“A”,s[1] 将是“Abcdefg”,

            如果您正在从控制台读取以下行,那么

            A abcdef B bhfhhhfh C chgghh
            

            拆分后s[0]= "A", s[1]="abcdef " s[2]= "B", s[3]="bhfhhhfh " s[4]= "C", s[5]="chgghh"

            在这种情况下,只有 A(String) 会调用,因为您只检查 s[0] 和 s[1]

            如果你想调用所有方法循环执行它

            for(int i=0;i<s.length;i=i+2){
              if (s[i] == "A")
                      A(s[i+1]);
                  if (s[i] == "B")
                      B(s[i+1]);
                  if (s[i] == "C")
                      C(s[i+1]);
            } 
            

            编辑 如果你不想写 if 那么你可以使用 switch

            开关 (s[0]) { 案例“A”: A(s(1)); 休息; 案例“B”: B(s(1)); 休息; 案例“C”: C(s(1)); 休息; . . . . . .

            }

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2019-08-26
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-11-14
              • 1970-01-01
              相关资源
              最近更新 更多