简体   繁体   English

使用值和引用参数类型重载的方法

[英]Methods overloading with value and reference parameter types

I have the following code : 我有以下代码:

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 ) );

        }
    }

This code work well despite that methods signature are differenciated only be the out keyword. 尽管方法签名仅与out关键字相区别,但此代码仍能正常工作。

But the following code didn't work : 但是以下代码不起作用:

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 ) );

        }
    }

Why this code didn't work ? 为什么这段代码不起作用? Are keywords like ref and out part of methods signatures? 关键字如ref和out方法签名的一部分?

out parameter modifier (C# Reference) out参数修饰符(C#参考)

Although the ref and out keywords cause different run-time behavior, they are not considered part of the method signature at compile time. 虽然ref和out关键字会导致不同的运行时行为, 但在编译时它们不会被视为方法签名的一部分。 Therefore, methods cannot be overloaded if the only difference is that one method takes a ref argument and the other takes an out argument. 因此,如果唯一的区别是一个方法采用ref参数而另一个方法采用out参数,则方法不能重载。

Also see: ref (C# Reference ) 另见: ref(C#参考

Members of a class can't have signatures that differ only by ref and out. 一个类的成员不能只有ref和out的签名。 A compiler error occurs if the only difference between two members of a type is that one of them has a ref parameter and the other has an out parameter. 如果类型的两个成员之间的唯一差异是其中一个具有ref参数而另一个具有out参数,则会发生编译器错误。

To quote slightly differently to the other answers, this is from section 3.6 of the C# 5 specification, which I find rather clearer and more precise than the "reference guide": 引用与其他答案略有不同,这是来自C#5规范的第3.6节,我发现它比“参考指南”更清晰,更精确:

Although out and ref parameter modifiers are considered part of a signature, members declared in a single type cannot differ in signature solely by ref and out. 虽然outref参数修饰符被认为是签名的一部分,但在单一类型中声明的成员只能通过ref和out在签名上有所不同。 A compile-time error occurs if two members are declared in the same type with signatures that would be the same if all parameters in both methods with out modifiers were changed to ref modifiers. 如果在具有out修饰符的两个方法中的所有参数都更改为ref修饰符的情况下,如果两个成员在同一类型中声明具有相同签名的成员,则会发生编译时错误。 For other purposes of signature matching (eg, hiding or overriding), ref and out are considered part of the signature and do not match each other. 对于签名匹配的其他目的(例如,隐藏或覆盖), refout被认为是签名的一部分并且彼此不匹配。 (This restriction is to allow C# programs to be easily translated to run on the Common Language Infrastructure (CLI), which does not provide a way to define methods that differ solely in ref and out .) (此限制是为了允许C#程序轻松转换为在公共语言基础结构(CLI)上运行,这不提供定义不同于refout方法的方法。)

Note that a parameter type of dynamic is slightly similar here - as far as the CLR is concerned, that's just a parameter of type object , so this is invalid: 请注意, dynamic的参数类型在这里略有相似 - 就CLR而言,这只是object类型的参数,因此这是无效的:

void InvalidOverload(object x) {}
void InvalidOverload(dynamic x) {}

In that case, however, it's fine for a method with a parameter type of dynamic to override one with a parameter type of object or vice versa - the important point there is that they're equivalent to callers , whereas that isn't true of out / ref . 但是,在这种情况下,对于参数类型为dynamic ,可以使用参数类型的object覆盖一个方法,反之亦然 - 重要的一点是,它们等同于调用者 ,而不是out / ref

This is by specification. 这是规范。 According to MSDN page out parameter modifier (C# Reference) 根据MSDN页面输出参数修饰符(C#参考)

Although the ref and out keywords cause different run-time behavior, they are not considered part of the method signature at compile time. 虽然ref和out关键字会导致不同的运行时行为,但在编译时它们不会被视为方法签名的一部分。 Therefore, methods cannot be overloaded if the only difference is that one method takes a ref argument and the other takes an out argument. 因此,如果唯一的区别是一个方法采用ref参数而另一个方法采用out参数,则方法不能重载。 The following code, for example, will not compile: 例如,以下代码将无法编译:

it's basically a compilation error as both ref and out are almost same. 它基本上是一个编译错误,因为ref和out几乎相同。 both are almost same but a value you pass a out parameter need not be initialised. 两者几乎相同,但是传递out参数的值不需要初始化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM