我如何向用户提供向我的字典中添加任何类型的方法的可能性<;字符串,委派>;

本文关键字:方法 可能性 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修饰符定义委托吗?答案显然是否定的,因为编译器在方法调用中将额外的参数转换为数组,但不用于委托。有关一些解决方案,请参阅链接。