C# 簽名與重載

2018-09-28 18:42 更新

簽名與重載

方法、實(shí)例構(gòu)造器、索引器和操作符由其簽名來(lái)鑒定:

  • 方法簽名由方法名、類(lèi)型參數(shù)成員以及形參的類(lèi)型與種類(lèi)(值 value、引用 reference 或輸出 output),按照從左到右的順序構(gòu)成。為此,出現(xiàn)在方法形參內(nèi)的類(lèi)型參數(shù)的識(shí)別并不根據(jù)它們的名字,而是依次根據(jù)它們?cè)诜椒?lèi)型實(shí)參類(lèi)表中的位置。
  • 實(shí)例構(gòu)造函數(shù)的簽名由每個(gè)形參的類(lèi)型和種類(lèi)(值 value、引用 reference 或輸出 output)從左到右構(gòu)成。具體來(lái)說(shuō),實(shí)例構(gòu)造函數(shù)簽名不包含最右側(cè) params 修飾符(params modifier)指定的參數(shù)。
  • 索引器簽名由其每個(gè)形參的類(lèi)型自左而右地構(gòu)成。具體來(lái)說(shuō),索引器簽名不包含元素類(lèi)型,也不包含最右側(cè) params 修飾符(params modifier)指定的參數(shù)。
  • 操作符簽名由簽名符名和形參類(lèi)型自左而右構(gòu)成。具體來(lái)說(shuō),操作符簽名不包含結(jié)果類(lèi)型。

簽名能使用類(lèi)、結(jié)構(gòu)或接口的成員的重載機(jī)制:

  • 允許類(lèi)、結(jié)構(gòu)或接口通過(guò)聲明多個(gè)同名方法對(duì)其重載,只要它們的簽名在類(lèi)、結(jié)構(gòu)或接口中是唯一的即可;
  • 允許類(lèi)或結(jié)構(gòu)的實(shí)例構(gòu)造函數(shù)通過(guò)聲明多個(gè)實(shí)例構(gòu)造函數(shù)對(duì)其重載,只要它們的簽名在類(lèi)或結(jié)構(gòu)中是唯一的即可;
  • 允許類(lèi)、結(jié)構(gòu)或接口中的索引器通過(guò)聲明多個(gè)索引器對(duì)其重載,只要它們的簽名在類(lèi)、結(jié)構(gòu)或接口中是唯一的即可;
  • 允許類(lèi)或結(jié)構(gòu)的操作符通過(guò)聲明多個(gè)操作符對(duì)其重載,只要它們的簽名在類(lèi)或結(jié)構(gòu)中是唯一的即可。

雖然 outref 參數(shù)修飾符是構(gòu)成簽名的一部分,但不能僅通過(guò) refout 修飾符來(lái)區(qū)分成員簽名。如果兩個(gè)成名聲明為相同簽名的類(lèi)型(即使它們內(nèi)的方法的形參修飾符從 out 變?yōu)?ref),那么將出現(xiàn)一個(gè)「編譯時(shí)錯(cuò)誤」。為了簽名匹配的其他用途(比如隱藏 hidden 或重寫(xiě) overriding),refout 是構(gòu)成簽名的一部分,以便相互不匹配。(這個(gè)限制允許 C# 程序能輕易轉(zhuǎn)換為能運(yùn)行在公共語(yǔ)言基礎(chǔ)結(jié)構(gòu)(Common Language Infrastructure,CLI)上,CLI 并未提供方式去定義只通過(guò) refout 進(jìn)行區(qū)別的方法)。

由于簽名的緣故,object 類(lèi)型和 dynamic 類(lèi)型被認(rèn)為是一樣的。因此不能僅通過(guò) objectdynamic 來(lái)區(qū)別在單一類(lèi)型中的成員聲明。

下例展示了一組重載的成員聲明及其簽名。

interface ITest
{
    void F();                  // F()
    void F(int x);             // F(int)
    void F(ref int x);         // F(ref int)
    void F(out int x);         // F(out int)   錯(cuò)誤
    void F(int x, int y);      // F(int, int)
    int F(string s);           // F(string)
    int F(int x);              // F(int)       錯(cuò)誤
    void F(string[] a);        // F(string[])
    void F(params string[] a); // F(string[])  錯(cuò)誤
}

注意,任何 refout 參數(shù)修飾符(第十章第 6.1 節(jié))都是簽名的一部分。因此,F(int)F(ref int) 都是唯一的簽名。但是 F(ref int)F(out int) 不能定義在同一個(gè)接口內(nèi),因?yàn)楹灻荒軆H從 refout 加以區(qū)分。同樣的,返回類(lèi)型和 params 修飾符都不是簽名的一部分,所以不可能僅基于返回類(lèi)型或是否包含 params 修飾符來(lái)區(qū)別重載,故而上面的方法聲明 F(int)F(params string[]) 會(huì)引發(fā)一個(gè)「編譯時(shí)錯(cuò)誤」。

以上內(nèi)容是否對(duì)您有幫助:
在線(xiàn)筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)