[英]Methods overloading with value and reference parameter types
我有以下代碼:
class Calculator
{
public int Sum(int x, int y)
{
return x + y;
}
public int Sum(out int x, out int y)
{
x = y = 10;
return x + y;
}
}
class Program
{
static void Main(string[] args)
{
int x = 10, y = 20;
Calculator calculator = new Calculator();
Console.WriteLine ( calculator.Sum ( x , y ) );
Console.WriteLine ( calculator.Sum ( out x , out y ) );
}
}
盡管方法簽名僅與out
關鍵字相區別,但此代碼仍能正常工作。
但是以下代碼不起作用:
class Calculator
{
public int Sum(ref int x, ref int y)
{
return x + y;
}
public int Sum(out int x, out int y)
{
x = y = 10;
return x + y;
}
}
class Program
{
static void Main(string[] args)
{
int x = 10, y = 20;
Calculator calculator = new Calculator();
Console.WriteLine ( calculator.Sum ( ref x , ref y ) );
Console.WriteLine ( calculator.Sum ( out x , out y ) );
}
}
為什么這段代碼不起作用? 關鍵字如ref和out方法簽名的一部分?
雖然ref和out關鍵字會導致不同的運行時行為, 但在編譯時它們不會被視為方法簽名的一部分。 因此,如果唯一的區別是一個方法采用ref參數而另一個方法采用out參數,則方法不能重載。
另見: ref(C#參考 )
一個類的成員不能只有ref和out的簽名。 如果類型的兩個成員之間的唯一差異是其中一個具有ref參數而另一個具有out參數,則會發生編譯器錯誤。
引用與其他答案略有不同,這是來自C#5規范的第3.6節,我發現它比“參考指南”更清晰,更精確:
雖然
out
和ref
參數修飾符被認為是簽名的一部分,但在單一類型中聲明的成員只能通過ref和out在簽名上有所不同。 如果在具有out
修飾符的兩個方法中的所有參數都更改為ref
修飾符的情況下,如果兩個成員在同一類型中聲明具有相同簽名的成員,則會發生編譯時錯誤。 對於簽名匹配的其他目的(例如,隱藏或覆蓋),ref
和out
被認為是簽名的一部分並且彼此不匹配。 (此限制是為了允許C#程序輕松轉換為在公共語言基礎結構(CLI)上運行,這不提供定義不同於ref
和out
方法的方法。)
請注意, dynamic
的參數類型在這里略有相似 - 就CLR而言,這只是object
類型的參數,因此這是無效的:
void InvalidOverload(object x) {}
void InvalidOverload(dynamic x) {}
但是,在這種情況下,對於參數類型為dynamic
,可以使用參數類型的object
覆蓋一個方法,反之亦然 - 重要的一點是,它們等同於調用者 ,而不是out
/ ref
這是規范。 根據MSDN頁面輸出參數修飾符(C#參考)
雖然ref和out關鍵字會導致不同的運行時行為,但在編譯時它們不會被視為方法簽名的一部分。 因此,如果唯一的區別是一個方法采用ref參數而另一個方法采用out參數,則方法不能重載。 例如,以下代碼將無法編譯:
它基本上是一個編譯錯誤,因為ref和out幾乎相同。 兩者幾乎相同,但是傳遞out參數的值不需要初始化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.