方法组(C#In Depth) - 需要帮助更好地理解方法组是什么

时间:2011-01-21 15:12:01

标签: c#

所以我已经阅读了一些与“什么是方法组”相关的StackOverflow问题以及其他互联网文章,它们在底线都说同样的事情 - 方法组是“一组重载方法” ”

然而,阅读Jon Skeet的“C#In Depth(第二版)”,他在Lambda表达式的背景下陈述了关于方法组的以下措辞(第9.4.1章)

  

更改原因:简化通用方法调用

     

类型推断在少数情况下发生。我们已经看到它适用于隐含的     类型化数组,当您尝试隐式转换方法组时也需要它     到委托类型。转换发生时,这可能会特别混乱     当您使用方法组作为另一个方法的参数时:使用重载     被调用的方法,以及方法中方法的重载     小组,和泛型方法的可能性,潜力的集合     转换可能是巨大的。“

任何方法组都不只是分配一组重载方法,或者他说你实际上可以创建一个保留整个方法组的委托。或者完全不同的东西,我不太了解。

有人可以在这里解释一下他的陈述是什么吗?

谢谢,

3 个答案:

答案 0 :(得分:14)

Jon描述的场景是这样的:

int M() {...}
string M<T>(T t) {...}
double M<T>(List<T> t) {...} 
static void M(double d) {...}
... etc ...

void N(Func<int> f) {...}
void N<T>(Action<T> a) {...}
void N<T>(Func<IEnumerable<T>> f) {...}
... etc ...

N(M);

N和M都是方法组,可能包含许多方法,其中一些可能是通用的。编译器提出的问题是“确定哪些方法N和M是开发人员想要的方法,如果预期的方法是通用的,则计算出类型参数”。

为了完成所有这一切,编译器必须尝试每个可能的N,然后找出每个可能的M中的哪个与N的重载的形式参数的委托类型兼容。它必须丢弃那些工作,然后从所有那些潜在的数百或数千个组合中,找出哪一个是“最好的”,如果有的话。这在语义分析中是一个棘手的问题。

答案 1 :(得分:4)

方法组是一个表示重载方法集的表达式,因此很明显他说的是使用这样的表达式创建委托。 E.g:


class Foo
{
public static void M() {}
public static void M(int _) {}
}
...
Action a = new Action(Foo.M); // Foo.M is a method group here.

您还可以查看C#规范以获取更多详细信息。

表达式分类为以下之一:
...
•方法组,它是由成员查找(第7.4节)产生的一组重载方法。方法组可以具有关联的实例表达式和关联的类型参数列表。调用实例方法时,评估实例表达式的结果将成为由此表示的实例(第7.6.7节)。方法组在invocation-expression(第7.6.5节),delegate-creation-expression(第7.6.10.5节)和is运算符的左侧允许,并且可以隐式转换为兼容的委托类型(6.6节)。在任何其他上下文中,分类为方法组的表达式会导致编译时错误。

答案 2 :(得分:2)

他是不是只是说当你提供一个methodGroup作为参数时,很难准确地推断出你的意思,因为它可能是该组中的任何方法?

鉴于不同的重载具有不同的签名(假设通用方法使方法签名更加模糊)如果您只是将方法组作为参数,则很难准确地确定参数的类型。 / p>