我如何向用户提供向我的字典中添加任何类型的方法的可能性<;字符串,委派>;
本文关键字:方法 可能性 lt 字符串 gt 委派 类型 任何 用户 我的 添加 | 更新日期: 2023-09-27 18:29:28
我需要提供向Dictionary添加任何返回double并接受任何数量的double参数的方法的可能性。请帮帮我。
class Program
{
Dictionary<string, Delegate> _functions;
static double MyFunc (double x, double y, double z, double q, double r, double t)
{
return 100;
}
// and the user can create his functions with any amount of parameters
static void AddFunction (Delegate d)
{
_functions.Add (d.Method.Name, d);
}
static void Main (string [] args)
{
_functions = new Dictionary<string, Delegate> ();
Program.AddFunction(MyFunc);
}
}
好吧,我不确定你打算如何调用它。由于您有变量数量的输入,因此可以将它们视为数组输入。
delegate double MyDictionaryDelegate(params double[] input);
static Dictionary<string, MyDictionaryDelegate> _functions;
static void AddFunction (MyDictionaryDelegate d)
{
_functions.Add(d.Method.Name, d);
}
但这基本上将您调用的函数转换为处理集合(具有这意味着的任何好处/限制):
public static double MyFunc (params double[] input)
{
return input.Sum();
}
所以你的用法可能是:
_functions = new Dictionary<string, MyDictionaryDelegate> ();
AddFunction(MyFunc);
Console.WriteLine(_functions["MyFunc"](1, 2.5, 0));//3.5
但我怀疑你宁愿保留参数参数的原始列表,而不是像这样的列表:
public static double AnotherFunc(double x, double y, double z)
{
return x + y + z;
}
您可以简单地拥有一个包装器函数:
public static double AnotherFunc(params double[] input)
{
//preferably with some check that the proper number of
//input parameters are included
return AnotherFuncImpl(input[0], input[1], input[2]);
}
但总的来说,这对我来说似乎有点危险;我不确定我会推荐它。
EDIT:这里有另一个选项可以避免使用param double[] input
数组,并且始终具有固定的参数参数。像以前一样使用Delegate
,但必须使用它的DynamicInvoke
。此外,您还需要为您期望合理拥有的每个参数数量声明几个AddFunction
重载:
static Dictionary<string, Delegate> _functions;
private static void AddFunction (string functionName, Delegate d)
{
_functions.Add(functionName, d);
}
private static void AddFunction(Func<double> d)
{
_functions.Add(d.Method.Name, d);
}
private static void AddFunction(Func<double, double> d)
{
_functions.Add(d.Method.Name, d);
}
private static void AddFunction(Func<double, double, double> d)
{
_functions.Add(d.Method.Name, d);
}
private static void AddFunction(Func<double, double, double, double> d)
{
_functions.Add(d.Method.Name, d);
}
//additional overloads up to N parameters
那么用法可能是:
public static double MyFunc(double x, double y, double z)
{
return x + y + z;
}
_functions = new Dictionary<string, Delegate> ();
AddFunction(MyFunc);
Console.WriteLine(_functions["MyFunc"].DynamicInvoke(1, 2.5, 0));//3.5
但是,如果调用者没有正确地使用所需参数的确切数量调用DynamicInvoke
(不多也不少),这可能会再次失败。
我仍然觉得,总的来说,无论你在做什么,都会从不同的设计中受益。
定义一个新的类对象,该对象具有所需的委托和参数列表,然后dictionary<string, clsObject>
将是定义字典的方式。
将方法添加到集合时将其转换为Func<T1, T2, .., TResult>
:
Program.AddFunction(
(Func<double, double, double, double, double, double, double>)MyFunc);
您需要声明您的委托返回一个double,并取一个doubles参数,这是一个完整的工作示例。
public class Widget
{
// declares a delegate called AddDelegate that takes a param of doubles
public delegate double AddDelegate(params double[] dbls);
Dictionary<string, AddDelegate> functions;
public Widget()
{
functions = new Dictionary<string, AddDelegate>();
}
public void Add(AddDelegate d)
{
functions.Add(d.Method.Name, d);
}
public void Run()
{
foreach (var kvp in functions)
{
// write out the name and result of each function added to our list
Console.Write(kvp.Key);
Console.Write(": ");
Console.Write(kvp.Value(10.0, 10.0, 10.0, 10.0));
}
}
}
class Program
{
static double CalcDouble(params double[] dbls)
{
double total = 0.0;
foreach (double d in dbls)
{
total += d;
}
return total;
}
static void Main(string[] args)
{
var w = new Widget();
w.Add(new Widget.AddDelegate(CalcDouble));
w.Run();
}
}
您的意思是用参数上的params
修饰符定义委托吗?答案显然是否定的,因为编译器在方法调用中将额外的参数转换为数组,但不用于委托。有关一些解决方案,请参阅链接。