Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
176 views
in Technique[技术] by (71.8m points)

.net - C# optional parameters on overridden methods

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();
    }
}
Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can disambiguate by calling:

this.MyMethod();

(in MyMethod2())

Whether it is a bug is tricky; it does look inconsistent, though. ReSharper warns you simply not to have changes to the default value in an override, if that helps ;p Of course, ReSharper also tells you the this. is redundant, and offers to remove it for you ... which changes the behaviour - so ReSharper also isn't perfect.

It does look like it could qualify as a compiler bug, I'll grant you. I'd need to look really carefully to be sure... where's Eric when you need him, eh?


Edit:

The key point here is the language spec; let's look at §7.5.3:

For example, the set of candidates for a method invocation does not include methods marked override (§7.4), and methods in a base class are not candidates if any method in a derived class is applicable (§7.6.5.1).

(and indeed §7.4 clearly omits override methods from consideration)

There's some conflict here.... it states that the base methods are not used if there is an applicable method in a derived class - which would lead us to the derived method, but at the same time, it says that methods marked override are not considered.

But, §7.5.1.1 then states:

For virtual methods and indexers defined in classes, the parameter list is picked from the most specific declaration or override of the function member, starting with the static type of the receiver, and searching through its base classes.

and then §7.5.1.2 explains how the values are evaluated at the time of the invoke:

During the run-time processing of a function member invocation (§7.5.4), the expressions or variable references of an argument list are evaluated in order, from left to right, as follows:

...(snip)...

When arguments are omitted from a function member with corresponding optional parameters, the default arguments of the function member declaration are implicitly passed. Because these are always constant, their evaluation will not impact the evaluation order of the remaining arguments.

This explicitly highlights that it is looking at the argument list, which was previously defined in §7.5.1.1 as coming from the most specific declaration or override. It seems reasonable that this is the "method declaration" that is referred to in §7.5.1.2, thus the value passed should be from the most derived up-to the static type.

This would suggest: csc has a bug, and it should be using the derived version ("bbb bbb") unless it is restricted (via base., or casting to a base-type) to looking at the base method declarations (§7.6.8).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...