C#中的方法签名

时间:2012-01-10 18:44:40

标签: c#

以下

中的方法签名是什么
int DoSomething(int a, int b);

返回类型是否是签名的一部分???

7 个答案:

答案 0 :(得分:68)

返回类型不是C#中方法签名的一部分。只有方法名称及其参数 types (但不是参数 names )才是签名的一部分。例如,您不能使用这两种方法:

int DoSomething(int a, int b);
string DoSomething(int a, int b);

要明确:方法不能根据其返回类型重载。它们必须具有唯一名称,唯一参数类型或以不同方式传递其参数(例如,使用outref)。

修改:要回答原始问题,方法的方法签名为:

DoSomething(int, int)

请注意,这一切都适用于普通方法。如果你在谈论delegate s,那么你应该看看keyboardP的答案。 (简短版本:返回类型IS代表签名的一部分)。

答案 1 :(得分:46)

  

返回类型是否是签名的一部分?

这取决于您提出问题的原因。你为什么关心?

方法签名有两种定义。 C#语言定义 not 包含返回类型,并使用方法的签名来确定是否允许两个重载。一种类型中不允许使用两种具有相同签名的方法。由于C#不认为返回类型是签名的一部分,因此C#不允许两个仅在返回类型上有所不同的方法以相同的类型声明。

然而,CLR确实包含签名中的返回类型。 CLR允许两种方法属于同一类型,只有返回类型不同。

更具体一点:在C#中,签名包含以下方法:

  • 名称
  • 类型参数的数量
  • 正式参数的数量
  • 每个形式参数的类型
  • out / ref / value-ness of each formal parameter

附加以下附加说明:

  • 泛型类型参数约束不是签名
  • 的一部分
  • 返回类型不是签名的一部分
  • 类型参数和形式参数名称不是签名的一部分
  • 两个方法可能与 in out / ref
  • 不同

在CLR中,签名包括:

  • 名称
  • 类型参数的数量
  • 正式参数的数量
  • 每个形式参数的类型,包括modopts和modreqs
  • 返回类型,包括modopts和modreqs
  • 每个形式参数的ref / value-ness

请注意,CLR不区分" ref int"和" out int"在考虑签名时。请注意,CLR 区分modopt / modreq类型。 (C#编译器处理modopt / modreq类型的方式过于复杂,无法在此总结。)

答案 2 :(得分:13)

来自MSDN:

  

方法的签名包括方法的名称以及每个形式参数的类型和种类(值,引用或输出),按从左到右的顺序考虑。 方法的签名特别不包括返回类型

修改:这是来自旧文档。从那时起,“签名”的定义似乎发生了变化。现在,一个方法有两个不同的签名,一个用于重载,另一个用于确定委托兼容性。有关详细信息,请参阅下面的keyboardP答案。

答案 3 :(得分:13)

来自MSDN

  

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

为了澄清,在您的示例中,返回类型不是签名的一部分。但是,当您匹配代理的签名时,它将被视为签名的一部分。来自MSDN

  

与委托的签名匹配的任何方法,由其组成   返回类型和参数,可以分配给委托。这个   make可以以编程方式更改方法调用,也可以   将新代码插入现有类。只要你知道   委托的签名,您可以指定自己的委托方法。

所以我相信它是基于背景的。大多数情况下,如您的代码所示,返回类型不是它的一部分。但是,在授权的背景下,它被认为是其中的一部分。

答案 4 :(得分:5)

DoSomething(int a, int b);

是方法签名,

int是返回类型。

看看这个:Signatures and overloading

答案 5 :(得分:0)

签名不包含返回类型。参数名称都没有。在您的情况下,它将是DoSomething(int, int)

答案 6 :(得分:0)

在方法具有通用参数的情况下,对签名的理解变得更加混乱。

在类级别上声明的泛型类型被视为普通类型。

但是在方法级别声明的泛型类型被视为方法的泛型参数中的索引。

例如,所有这些方法都具有不同的签名。

class MyClass<TValue>
{
    public void F(TValue v) { }       // generics: 0, arg: TValue
    public void F<X>(TValue v) { }    // generics: 1, arg: TValue
    public void F<X, Y>(TValue v) { } // generics: 2, arg: TValue

    public void F<X>(X v) { }    // generics: 1, arg: 0
    public void F<X, Y>(X v) { } // generics: 2, arg: 0
    public void F<X, Y>(Y v) { } // generics: 2, arg: 1
}