且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

对重载方法C#的可选参数

更新时间:2023-02-14 18:15:13

有一件事值得一提的这里,是,重写版本被称为每次。覆盖更改为:

 公共覆盖无效的MyMethod(字符串s =BBB)
{
  Console.Write(来源:);
  base.MyMethod(多个);
}
 

和输出结果是:

 来源:BBB
来源:AAA
 

在一个类中的方法可以做一个或两个以下的:

  1. 它定义为其它code接口来调用。
  2. 在它定义一个实现执行调用时。

这可能两者都做,作为一个抽象的方法不只是前者。

BBB 呼叫的MyMethod()在确定 C $ C> AAA 。

由于在 BBB一个覆盖,调用该方法会导致一个实施 BBB 被调用。

现在,在 AAA 定义通知要求两件事情code(当然,其他几个人也无所谓的在这里)。

  1. 签名无效的MyMethod(字符串)
  2. (适用于支持它的语言),因此编译$ C $形式c当为单个参数的默认值是AAA的MyMethod()如果没有办法匹配的MyMethod()可以发现,你可以用电话更换为'的MyMethod(AAA )。

那么,这就是在 BBB通话的作用:编译器看到调用的MyMethod(),没有按找不到方法的MyMethod()但是找到一个方法的MyMethod(字符串)。它也看到,在它被定义有AAA的默认值,因此在编译时它改变这调用的MyMethod的地方(AAA)

这是在 BBB AAA 被认为是地方 AAA 的定义方法,即使在 BBB ,覆盖,使他们的可以的过度缠身。

在运行时,的MyMethod(字符串)被调用,参数AAA。因为有一个重写形式,即所谓的形式,但它不叫与BBB,因为该值无关与运行时执行,而且与编译时定义

添加这一点。该定义被检查因此改变什么参数用于通话。变化,以及

编辑:为什么这似乎更直观我

就个人而言,既然我说的是什么直观的就只能是个人的,我觉得这是更直观,原因如下:

如果我在编写 BBB 那么是否调用或覆盖的MyMethod(字符串),我会想起那作为做 AAA 的东西 - 这是 BBB 。就拿上做 AAA 的东西,但它做 AAA 的东西都一样。因此,无论是打电话还是压倒一切,我要知道的事实,这是 AAA 的定义的MyMethod(字符串)

如果我打电话所用code BBB ,我倒是觉得使用 BBB 的东西。我可能不是很清楚其中的 AAA 最初定义的,而且我也许认为这仅仅是一个实现细节(如果我也没使用 AAA 接口附近)。

编译器的行为符合我的直觉,这就是为什么当第一次读它在我看来,单有一个错误的问题。经考虑,我看不出任何符合规定的行为比其他更好。

对于这个问题,虽然,同时继续保持在个人层面上,我从来没有用抽象的,虚拟或重载方法可选参数,如果覆盖别人的说没有,我会配合他们的。

Seems like in .NET Framework there is an issue with optional parameters when you override the method. The output of the code below is: "bbb" "aaa" . But the output I'm expecting is: "bbb" "bbb" .Is there a solution for this. I know it can be solved with method overloading but wondering the reason for this. Also the code works fine in Mono.

class Program
{
    class AAA
    {
        public virtual void MyMethod(string s = "aaa")
        {
            Console.WriteLine(s);
        }

        public virtual void MyMethod2()
        {
            MyMethod();
        }
    }

    class BBB : AAA
    {
        public override void MyMethod(string s = "bbb")
        {
            base.MyMethod(s);
        }

        public override void MyMethod2()
        {
            MyMethod();
        }
    }

    static void Main(string[] args)
    {
        BBB asd = new BBB();
        asd.MyMethod();
        asd.MyMethod2();
    }
}

One thing worth noting here, is that the overridden version is called each time. Change the override to:

public override void MyMethod(string s = "bbb")
{
  Console.Write("derived: ");
  base.MyMethod(s);
}

And the output is:

derived: bbb
derived: aaa

A method in a class can do one or two of the following:

  1. It defines an interface for other code to call.
  2. It defines an implementation to execute when called.

It may not do both, as an abstract method does only the former.

Within BBB the call MyMethod() calls a method defined in AAA.

Because there is an override in BBB, calling that method results in an implementation in BBB being called.

Now, the definition in AAA informs calling code of two things (well, a few others too that don't matter here).

  1. The signature void MyMethod(string).
  2. (For those languages that support it) the default value for the single parameter is "aaa" and therefore when compiling code of the form MyMethod() if no method matching MyMethod() can be found, you may replace it with a call to `MyMethod("aaa").

So, that's what the call in BBB does: The compiler sees a call to MyMethod(), doesn't find a method MyMethod() but does find a method MyMethod(string). It also sees that at the place where it is defined there's a default value of "aaa", so at compile time it changes this to a call to MyMethod("aaa").

From within BBB, AAA is considered the place where AAA's methods are defined, even if overridden in BBB, so that they can be over-ridden.

At run-time, MyMethod(string) is called with the argument "aaa". Because there is a overridden form, that is the form called, but it is not called with "bbb" because that value has nothing to do with the run-time implementation but with the compile-time definition.

Adding this. changes which definition is examined, and so changes what argument is used in the call.

Edit: Why this seems more intuitive to me.

Personally, and since I'm talking of what is intuitive it can only be personal, I find this more intuitive for the following reason:

If I was coding BBB then whether calling or overriding MyMethod(string), I'd think of that as "doing AAA stuff" - it's BBBs take on "doing AAA stuff", but it's doing AAA stuff all the same. Hence whether calling or overriding, I'm going to be aware of the fact that it was AAA that defined MyMethod(string).

If I was calling code that used BBB, I'd think of "using BBB stuff". I might not be very aware of which was originally defined in AAA, and I'd perhaps think of this as merely an implementation detail (if I didn't also use the AAA interface nearby).

The compiler's behaviour matches my intuition, which is why when first reading the question it seemed to me that Mono had a bug. Upon consideration, I can't see how either fulfils the specified behaviour better than the other.

For that matter though, while remaining at a personal level, I'd never use optional parameters with abstract, virtual or overridden methods, and if overriding someone else's that did, I'd match theirs.