Можно ли хранить функции в словаре?
У меня есть сообщение, входящее в мое приложение С#, которое является объектом, сериализованным как JSON, когда я де-сериализую его. У меня есть "Имя" string
и "Полезная нагрузка" string[]
, я хочу иметь возможность возьмите "Имя" и найдите его в словаре функций, используя массив "Полезная нагрузка" в качестве его параметров, а затем возьмите вывод для возврата клиенту, отправляющему сообщение, возможно ли это на С#?
Я нашел ответ здесь, где вторая часть кажется правдоподобной, но я не знаю, что я упоминаю с помощью State
Ответы
Ответ 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.
Надеюсь, что это поможет!