Is it possible to store functions in a dictionary?

前端 未结 5 737
萌比男神i
萌比男神i 2021-02-01 14:46

I have a message coming into my C# app which is an object serialized as JSON, when i de-serialize it I have a \"Name\" string and a \"Payload\" string[]

相关标签:
5条回答
  • 2021-02-01 15:18

    You can create a dictionary of string as a key and a Action<string[]> as a value and use it, for sample:

    var functions = new Dictionary<string, Action<string[]>>();
    
    functions.Add("compute", (p) => { /* use p to compute something*/ });
    functions.Add("load", (p) => { /* use p to compute something*/ });
    functions.Add("process", (p) => { /* use p to process something*/ });
    

    You could use it after you deserialize your message parameter, you could use the functions dictionary:

    public void ProcessObject(MessageDTO message)
    {
        if (functions.ContainsKey(message.Name))
        {
            functions[name](message.Parameters);
        }
    }
    
    0 讨论(0)
  • 2021-02-01 15:20

    It sounds like you probably want something like:

    Dictionary<string, Func<string[], int>> functions = ...;
    

    This is assuming the function returns an int (you haven't specified). So you'd call it like this:

    int result = functions[name](parameters);
    

    Or to validate the name:

    Func<string[], int> function;
    if (functions.TryGetValue(name, out function))
    {
        int result = function(parameters);
        ...
    }
    else
    {
        // No function with that name
    }
    

    It's not clear where you're trying to populate functions from, but if it's methods in the same class, you could have something like:

    Dictionary<string, Func<string[], int>> functions = 
        new Dictionary<string, Func<string[], int>>
    {
        { "Foo", CountParameters },
        { "Bar", SomeOtherMethodName }
    };
    
    ...
    
    private static int CountParameters(string[] parameters)
    {
        return parameters.Length;
    }
    
    // etc
    
    0 讨论(0)
  • 2021-02-01 15:28

    Yes.

    var functions = new Dictionary<string, Func<string[], string[]>>();
    functions.Add("head", x => x.Take(1).ToArray());
    functions.Add("tail", x => x.Skip(1).ToArray());
    var result = functions["tail"](new [] {"a", "b", "c"});
    
    0 讨论(0)
  • 2021-02-01 15:38

    Something similar to this:

    public class Methods
    {
        public readonly Dictionary<string, Func<string[], object>> MethodsDict = new Dictionary<string, Func<string[], object>>();
    
        public Methods()
        {
            MethodsDict.Add("Method1", Method1);
            MethodsDict.Add("Method2", Method2);
        }
    
        public string Execute(string methodName, string[] strs)
        {
            Func<string[], object> method;
    
            if (!MethodsDict.TryGetValue(methodName, out method))
            {
                // Not found;
                throw new Exception();
            }
    
            object result = method(strs);
    
            // Here you should serialize result with your JSON serializer
            string json = result.ToString();
    
            return json;
        }
    
        public object Method1(string[] strs)
        {
            return strs.Length;
        }
    
        public object Method2(string[] strs)
        {
            return string.Concat(strs);
        }
    }
    

    Note that you could make it all static, if the methods don't need to access data from somewhere else.

    The return type I chose for the delegates is object. In this way the Execute method can serialize it to Json freely.

    0 讨论(0)
  • 2021-02-01 15:40

    My solution with input parameters, and a int as Key of Invoke:

      private static Dictionary<int, Action> MethodDictionary(string param1, string param2, int param3) => new Dictionary<int, Action>
        {
                {1 , () =>   Method1(param1, param2, param3) },
                {2 , () =>   Method2(param1, param2, param3) },
                {3 , () =>   Method3(param1, param2, param3) },
                {4 , () =>   Method4(param1, param2, param3) },
                {5 , () =>   Method5(param1, param2, param3) }
        };
    

    And to invoke a method:

     var methodDictionary = MethodDictionary("param1", "param2", 1);
     methodDictionary[2].Invoke();
    

    This will execute Method2.

    Hope it helps!

    0 讨论(0)
提交回复
热议问题