我有这种功能
void func(params object[] parameters) {
//Function Body
}
它可以接受以下排序的参数
func(10, "hello", 30.0);
func(10,20);
等等。
我想为上述功能创建一个Action
委托。可能吗?如果不是那么为什么?
答案 0 :(得分:13)
您不能将现有的Action
代表与params
一起使用,但您可以这样声明自己的代理:
public delegate void ParamsAction(params object[] arguments)
然后:
// Note that this doesn't have to have params, but it can do
public void Foo(object[] args)
{
// Whatever
}
...
ParamsAction action = Foo;
action("a", 10, 20, "b");
当然你可以为你现有的方法创建一个Action<object[]>
- 但是你失去了它的params
方面,因为它没有在{{{}}中声明1}}。例如:
Action<T>
因此,如果您从想要使用public static void Foo(params object[] x)
{
}
...
Action<object[]> func = Foo;
func("a", 10, 20, "b"); // Invalid
func(new object[] { "a", 10, 20, "b" }); // Valid
的代码中调用代理,则需要一个委托类型,其中包含声明中的代理(根据第一部分) 。如果您只想创建一个接受params
的委托,那么您可以使用其签名中包含object[]
的方法创建Action<object[]>
的实例 - 它实际上只是一个修饰语。
答案 1 :(得分:0)
这是您在C#中遇到函数式编程限制的原因:您不能拥有一个具有可变数量的通用类型参数的委托(Action
委托具有固定数量的通用参数)。但是您可能会发现为每个参数创建泛型重载非常有用:
void func<T1>(T1 parameter1) { ... }
void func<T1,T2>(T1 parameter1, T2 parameter2) { ... }
void func<T1,T2,T3>(T1 parameter1, T2 parameter2, T3 parameter3) { ... }
这让你获得的是将这些函数作为参数传递的能力(即,简单地传递它们而不使用lambda表达式)。所以如果你有这样的功能:
void anotherFunc(Action<string, int> parameter) { ... }
然后你可以这样称呼它:
anotherFunc(func);