23

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

在谷歌上,我找到了各种定义:

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

那是什么意思method signature = method name + argument list?然后我看不出“方法”和“方法签名”之间的区别。

如果我有一个方法:

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

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

  • 富(整数,整数)
  • 富(int x,int y)
  • 福(34, 78)

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

4

7 回答 7

28

这里有许多正确的答案,它们将方法签名定义为方法名称、通用参数、形式参数参数以及形式参数类型和种类,而不是返回类型或“params”修饰符。

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

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

CLR 也不认为“out”和“ref”属于不同的形参类型;C# 可以。

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

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

两个签名都定义了一个方法 M,该方法采用“对 C 的引用”类型的参数。但是因为第一个是 const 引用而第二个不是,所以 C++ 语言认为这些是不同的签名。CLR 通过允许 C++/CIL 编译器为形式参数类型上的特殊“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# 规则。

于 2011-12-15T14:52:00.117 回答
13

来自 MSDN:

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

这里重要的部分是方法的返回类型不属于它的签名。因此,您不能重载仅因返回类型而异的方法!

于 2011-12-15T07:42:52.863 回答
10

方法签名是编译器可以用来识别方法的方法的属性集。

属性是:方法名称、参数个数、参数类型和参数顺序。

不同方法签名的示例:

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

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

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

于 2011-12-15T07:58:08.030 回答
5

方法签名包括以下几项:

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

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

于 2014-06-03T07:21:20.633 回答
1

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

于 2011-12-15T07:31:08.670 回答
0

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

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

于 2011-12-15T08:49:16.317 回答
-1

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

告诉:

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

更进一步,我在其他答案中没有看到:

"

“出于方法重载的目的,方法的返回类型不是方法签名的 一部分。但是,在确定委托与其指向的方法之间的兼容性时,它是方法签名的一部分”

于 2013-02-14T11:24:26.777 回答