0

我需要提供添加任何返回 double 的方法并将任何数量的 double 参数添加到 Dictionary 的可能性。请帮帮我。

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

5 回答 5

1

好吧,我不确定你打算如何准确地调用它。由于您有可变数量的输入,因此您可以将它们视为数组输入。

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

但这对我来说似乎总体上有点危险。我不确定我会推荐它。

编辑:这是避免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确切数量(不多也不少),这可能会失败。

总体而言,我仍然觉得,无论您在做什么,都会从不同的设计中受益。

于 2013-08-29T16:47:53.227 回答
0

您的意思是在其参数上定义一个带有params修饰符的委托吗?答案显然是否定的,因为编译器在方法调用中将附加参数转换为数组,而不是委托。有关一些解决方案,请参阅链接。

于 2013-08-29T16:46:17.917 回答
0

您需要将您的委托声明为返回双精度,并采用双精度参数,这是一个完整的工作示例。

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();
    }
}
于 2013-08-29T16:48:00.530 回答
0

将方法Func<T1, T2, .., TResult>添加到集合中时将其转换为 a:

Program.AddFunction(
    (Func<double, double, double, double, double, double, double>)MyFunc);
于 2013-08-29T16:43:53.850 回答
0

定义一个新的类对象,它具有您需要的委托和参数列表,然后dictionary<string, clsObject>就是您定义字典的方式。

于 2013-08-29T16:36:17.293 回答