簡體   English   中英

使用值和引用參數類型重載的方法

[英]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方法簽名的一部分?

out參數修飾符(C#參考)

雖然ref和out關鍵字會導致不同的運行時行為, 但在編譯時它們不會被視為方法簽名的一部分。 因此,如果唯一的區別是一個方法采用ref參數而另一個方法采用out參數,則方法不能重載。

另見: ref(C#參考

一個類的成員不能只有ref和out的簽名。 如果類型的兩個成員之間的唯一差異是其中一個具有ref參數而另一個具有out參數,則會發生編譯器錯誤。

引用與其他答案略有不同,這是來自C#5規范的第3.6節,我發現它比“參考指南”更清晰,更精確:

雖然outref參數修飾符被認為是簽名的一部分,但在單一類型中聲明的成員只能通過ref和out在簽名上有所不同。 如果在具有out修飾符的兩個方法中的所有參數都更改為ref修飾符的情況下,如果兩個成員在同一類型中聲明具有相同簽名的成員,則會發生編譯時錯誤。 對於簽名匹配的其他目的(例如,隱藏或覆蓋), refout被認為是簽名的一部分並且彼此不匹配。 (此限制是為了允許C#程序輕松轉換為在公共語言基礎結構(CLI)上運行,這不提供定義不同於refout方法的方法。)

請注意, 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM