是否可以将函数存储在字典中?

时间:2015-05-22 13:21:58

标签: c# dictionary

我有一条消息进入我的C#应用​​程序,这是一个序列化为JSON的对象,当我对其进行反序列化时,我有一个"名称" string和"有效负载" string[],我希望能够采用"名称"并使用" Payload"在函数字典中查找它。数组作为其参数,然后取输出返回发送消息的客户端,这可能在C#中吗?

我发现了一个堆栈溢出回答here,其中第二部分似乎有道理,但我不知道我用State

引用了什么

5 个答案:

答案 0 :(得分:49)

听起来你可能想要这样的东西:

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

这假设函数返回int(您没有指定)。所以你这样称呼它:

int result = functions[name](parameters);

或者验证名称:

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

您不清楚在哪里尝试填充functions,但如果它在同一个类中的方法,您可能会有以下内容:

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

答案 1 :(得分:5)

您可以创建一个字典string作为键,Action<string[]>作为值,并使用它,样本:

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*/ });

您可以在反序列化消息参数后使用它,可以使用functions字典:

public void ProcessObject(MessageDTO message)
{
    if (functions.ContainsKey(message.Name))
    {
        functions[name](message.Parameters);
    }
}

答案 2 :(得分:3)

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

答案 3 :(得分:2)

类似的东西:

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

请注意,如果方法不需要从其他地方访问数据,则可以全部static

我为代表选择的返回类型是object。通过这种方式,Execute方法可以自由地将它序列化为Json。

答案 4 :(得分:0)

我的输入参数解决方案,以及作为调用键的int:

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

并调用方法:

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

这将执行 Method2。

希望它有所帮助!