能否在字典中存储函数?

35

我有一条消息传入我的C#应用程序,它是一个序列化为JSON的对象,当我反序列化时,我有一个“Name”string和一个“Payload”string[],我想能够使用“Name”在函数字典中查找,并使用“Payload”数组作为其参数,然后将输出返回给发送消息的客户端,这在C#中可行吗?

我在这里找到了一个Stack Overflow答案,其中第二部分似乎是可行的,但我不知道我正在引用什么State

5个回答

54

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

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

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

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

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。

0

我的解决方案包括输入参数和一个整数作为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) }
    };

调用一个方法:

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

这将执行Method2。

希望能帮到你!


这些方法是否可以返回一个值? - Dror
这个不起作用,因为您的字典接受没有参数的方法,因为您写的是Dictionary<int, Action>而不是Dictionary<int, Action<param1,param2,param3>>。 - Berke Kaan Cetinkaya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接