方法签名的定义?

方法签名(或方法的签名)的正确定义是什么?

在谷歌上,我发现了各种定义:

它是方法名称和参数列表的组合

这是否意味着method signature = method name + argument list ? 然后我看不出“ 方法 ”和“ 方法签名 ”之间的区别。

如果我有一个方法:

 public void Foo(int x, int y) { ... } 

我的方法签名会是以下之一,还是两者都不是?

  • Foo(int,int)
  • Foo(int x,int y)
  • Foo(34,78)

如果有人问我该方法的方法签名是什么,我该怎么回答?

这里有一些正确的答案,它们将方法签名定义为方法名称,genericsarity,forms参数arity和forms参数类型和种类,但不是返回类型或“params”修饰符。

虽然这是正确的,但这里有一些细微之处。 C#语言定义方法签名的方式与CLR定义方法签名的方式不同,在C#和其他语言之间进行互操作时可能会导致一些有趣的问题。

对于CLR,方法签名由方法名称,genericsarity,forms参数arity,forms参数类型和种类以及返回类型组成。 所以有第一个区别; CLR考虑返回类型。

CLR也不认为“out”和“ref”具有不同的forms参数种类; C#的确如此。

CLR还有一个有趣的function叫做“可选和必需的类型修饰符”,通常称为“modopts”和“modreqs”。 可以使用另一种告诉您“主”类型的类型来注释方法签名中的类型。 例如,在C ++中,这是两个不同的签名:

 void M(C const & x); void M(C & x); 

两个签名都定义了一个方法M,它采用“引用C”类型的参数。 但是因为第一个是const引用而第二个不是,所以C ++语言认为这些是不同的签名。 CLR通过允许C ++ / CIL编译器在forms参数类型上为特殊的“this is const”类型发出modopt来实现这一点。

没有办法在C#中读取或设置mod,但C#编译器仍然知道它们并且会以某种方式尊重它们。 例如,如果您在C ++ / CIL中声明了一个公共虚方法,如:

 void V(C const * x) 

并且您在用C#编写的派生类中重写它,C#编译器将不会为您强制执行const正确性; C#编译器不知道const modopt的含义。 但是C#编译器将确保在modopt到位的情况下将重写方法发送到元数据中。 这是必要的,因为CLR需要覆盖和重写方法的签名才能匹配; 编译器必须遵守签名匹配的CLR规则,而不是C#规则。

来自MSDN:

方法的签名包括方法的名称以及每个forms参数的类型和种类(值,引用或输出),按从左到右的顺序考虑。 方法的签名特别不包括返回类型,也不包括可以为最右边的参数指定的params修饰符。

这里重要的部分是方法的返回类型不属于其签名。 所以你不能重载只有返回类型不同的方法!

方法签名是编译器可用于标识方法的方法的属性集。

attrbutes是:方法名称,参数数量,参数类型和参数顺序。

不同方法签名的示例:

 Foo() Foo(int) Foo(String) Foo(int, string) Foo(string, int) 

所有这些方法都不同,当您在代码中调用它们时,编译器可以使用方法签名推断您打算执行哪个方法。

不要忘记模块化编程中方法的范围……

方法签名包括以下项目:

  • 方法的名称。
  • 参数个数。
  • 数据类型和参数的顺序。

注意:返回类型不是签名的一部分。

在上面的示例中,方法签名是Foo(int x,int y)。 这一点很重要,因为在允许方法重载的语言(例如C#和Java)中,方法名称将相同,但签名必须不同。

C#语言规范(v 4.0)的第3.6节提供了有关方法签名的最精确答案:

方法的签名包括方法的名称,类型参数的数量以及每个forms参数的类型和种类(值,引用或输出),按从左到右的顺序考虑。 出于这些目的,在forms参数类型中出现的方法的任何类型参数不是通过其名称来标识,而是通过其在方法的类型参数列表中的序号位置来标识。 方法的签名特别不包括返回类型,可以为最右边的参数指定的params修饰符,也不包括可选的类型参数约束。

MSDN文章“方法(C#编程指南)”

讲述:

通过指定访问级别(如public或private),可选修饰符(如abstract或sealed),返回值,方法名称和任何方法参数,在类或结构中声明方法。 这些部分一起是该方法的标志。

而且,我还没有看到其他答案:

注意

为了方法重载的目的,方法的返回类型不是方法签名的一部分。但是, 当确定委托与它指向的方法之间的兼容性时 ,它是方法签名的一部分