【问题标题】:Method Signature in C#C# 中的方法签名
【发布时间】:2012-02-07 04:26:33
【问题描述】:

下面的方法签名是什么

int DoSomething(int a, int b);

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

【问题讨论】:

    标签: c#


    【解决方案1】:

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

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

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

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

    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
    }
    

    【讨论】:

      【解决方案2】:

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

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

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

      编辑:要回答您的原始问题,您的方法的方法签名是:

      DoSomething(int, int)
      

      请注意,这一切都适用于普通方法。如果您在谈论delegates,那么您应该看到keyboardP 的答案。 (简短版:返回类型是委托签名的一部分)。

      【讨论】:

      • @adamjmarkham:只有在子类中重写时才能这样做,而不是“取决于方法的作用”。而且我很确定返回类型是 not 签名的一部分。
      • 返回类型不是 my padawan 方法签名的一部分。
      • 这个答案确实需要取消标记为已接受,因为它不正确。 Eric Lippert 下面的回答正确地定义了构成方法签名的元素。
      • @0b101010 我的回答中的所有内容实际上都是正确的。 Eric 的回答也是正确的,而且肯定更全面(考虑到他的背景,这不足为奇),但这并没有降低这个答案的准确性。
      • @ean5533 我不同意。您声明“它们必须具有唯一的名称或唯一的参数类型。”没有提及将参数传递给参数的方式。这与参数类型本身是分开的。一个微妙但重要的观点。也许对答案的一个小更新可能会帮助未来的读者?鉴于这是公认的答案,他们可能不会费心阅读下面 Eric 的答案。
      【解决方案3】:

      来自MSDN

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

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

      任何匹配委托签名的方法,包括 返回类型和参数,可以分配给委托。这 使得可以以编程方式更改方法调用,并且 将新代码插入现有类。只要你知道 委托的签名,你可以分配自己的委托方法。

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

      【讨论】:

        【解决方案4】:

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

        这取决于你问这个问题的原因。你为什么在乎?

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

        但是,CLR 确实在签名中包含返回类型。 CLR 允许两个方法属于同一类型,仅返回类型不同。

        更具体地说:在 C# 中,签名由方法组成:

        • 姓名
        • 类型参数的数量
        • 形参个数
        • 每个形参的类型
        • 每个形式参数的输出/引用/值性

        带有以下附加说明:

        • 泛型类型参数约束不是签名的一部分
        • 返回类型不是签名的一部分
        • 类型参数和形式参数名称不是签名的一部分
        • 两种方法可能没有区别只有 in out/ref

        在 CLR 中,签名包括:

        • 姓名
        • 类型参数的数量
        • 形参个数
        • 每个形式参数的类型包括 modopts 和 modreqs
        • 返回类型包括 modopts 和 modreqs
        • 每个形式参数的引用/值性

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

        【讨论】:

        • 我一直在谷歌搜索,没有发现为什么 C# 团队决定返回类型不是签名的一部分?只有性能问题?你能解释一下吗? tks
        • 嗨,我想问和 Luis fillipe 一样的问题。
        • @mmhasannn:重载的签名必须不同。如果返回类型是签名的一部分,那么您可以使用两种仅在返回类型上有所不同的方法。这极大地复杂化了重载解析。
        • @LucaCremonesi:一点也不。重载解析不是 CLR 的功能。重载解析是 languages 的一项功能,而不是 runtimes 的一项功能。
        • @wishmaster35:如果您有一个带有签名string F&lt;T&gt;(int x) 的方法,那么x正式参数T类型参数int形参类型。当你调用它时:F&lt;double&gt;(123) 那么 123 是 argumentactual parameterdoubletype argument
        【解决方案5】:

        来自MSDN:

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

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

        【讨论】:

        • @gdoron 如果您拆分投票分数,您可以看到有人对页面上的每个答案都投了反对票。去搞清楚。编辑:现在他们也对这个问题投了反对票。
        • @gdoron - 不管怎样,keyboardP 的答案,它引用了更近期的文档,比我的要好得多。
        【解决方案6】:

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

        【讨论】:

          【解决方案7】:
          DoSomething(int a, int b);
          

          是方法签名,

          int 是返回类型。

          看看这个:Signatures and overloading

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-06-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-11-24
            • 2018-01-15
            • 2010-11-09
            相关资源
            最近更新 更多