Подтвердить что ты не робот

Можно ли хранить функции в словаре?

У меня есть сообщение, входящее в мое приложение С#, которое является объектом, сериализованным как JSON, когда я де-сериализую его. У меня есть "Имя" string и "Полезная нагрузка" string[], я хочу иметь возможность возьмите "Имя" и найдите его в словаре функций, используя массив "Полезная нагрузка" в качестве его параметров, а затем возьмите вывод для возврата клиенту, отправляющему сообщение, возможно ли это на С#?

Я нашел ответ здесь, где вторая часть кажется правдоподобной, но я не знаю, что я упоминаю с помощью State

4b9b3361

Ответ 1

Похоже, вы, вероятно, хотите что-то вроде:

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

Ответ 2

Вы можете создать словарь 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"});

Ответ 4

Что-то похожее на это:

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 свободно.

Ответ 5

Мое решение с входными параметрами и 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.

Надеюсь, что это поможет!