Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#:传递一个带有可变参数的方法作为另一个方法的参数_C# - Fatal编程技术网

C#:传递一个带有可变参数的方法作为另一个方法的参数

C#:传递一个带有可变参数的方法作为另一个方法的参数,c#,C#,所以这里我试图将一个带有随机签名的方法传递给Foo方法。但是没有任何运气。 问题是我可以通过任何行动。但是在一种方法上。 有什么帮助吗 class Bar { void M1(int a) { } void M2(string a, int b) { } Action<string, int, bool> A1 = (s, i, b) => {}; Action<int, float> A2 = (i, f) => {};

所以这里我试图将一个带有随机签名的方法传递给Foo方法。但是没有任何运气。
问题是我可以通过任何行动。但是在一种方法上。
有什么帮助吗

class Bar
{
    void M1(int a) { }
    void M2(string a, int b) { }

    Action<string, int, bool> A1 = (s, i, b) => {};
    Action<int, float> A2 = (i, f) => {};

    void Foo(Delegate f) {}

    void Test()
    {
        Foo(A1);
        Foo(A2);
        // Foo(M1); // nope
        // Foo(M2); // no way
    }
}
类栏
{
空M1(int a){}
void M2(字符串a,int b){}
动作A1=(s,i,b)=>{};
动作A2=(i,f)=>{};
void Foo(委托f){}
无效测试()
{
傅(A1);
Foo(A2);
//Foo(M1);//不
//Foo(M2);//不可能
}
}

另外,我正试图在Unity3d的Mono下实现这一点。

要做到这一点,您必须转换为具体的委托类型,如下所示:

void Test()
{
    Foo(A1);
    Foo(A2);
    Foo((Action<int>) M1);
    Foo((Action<string, int>)M2); 
}
void测试()
{
傅(A1);
Foo(A2);
Foo((行动)M1);
Foo((行动)M2);
}
原因是
M1
M2
是所谓的方法组。这仅仅意味着它们引用了一个或多个方法。为什么它可以不止一个?因为您可能有多个名为M1的方法,每个方法都接受不同的参数集。但是,即使您只有一个重载,就像在您的例子中一样,也可能有多个与该重载签名兼容的委托类型(可能是
Action
YourDelegateType
,声明为delegate void YourDelegateType(int arg),或其他任何类型)


这就是为什么没有从方法组到委托的隐式转换,您必须显式地将方法组转换为特定的委托类型。

这不是unity3d或mono所特有的,它只是语言的一部分<代码>M1和
M2
是“方法组”,而不是代表。方法组可以转换为任何兼容的委托类型,编译器拒绝从空中选择一种(如
Action
Func
类型)。是的,我知道。我刚刚提到它,以防有人根据C#3.0+的独特特性提出解决方案。一件事是可能存在多个重载。但在本例中,每个名称
M1
M2
只有一个重载。另一件事是可能存在多个兼容的具体委托类型。例如,使用
voidm3(objecta,intb){}
(仅此一个重载),调用
Foo(M3)
可以代表
Foo((动作)M3)
Foo((EventHandler)M3)。甚至
Foo((MyDel)M3)其中
MyDel
是您自己创建的某种类型。
操作
在C#中没有特殊的状态,因此编译器不会选择
操作
“从无到有”。此外,由于方法组转换可以进行协变和逆变,因此有时可以使用另一组类型参数。从前面继续我的例子,都是
Foo((Action)M3)
Foo((动作)M3)是可能的。确实有很多优点。很明显,如果不显式地选择委托类型,即使只存在一个重载,也无法将方法组转换为委托。感谢您的解释和解决方案。我完全满意。