Not able to understand output of methods with Optional Parameter

99 views Asked by At

Today I was writing a small program to understand the fundamentals of Optional Parameters of C#.

Following is the program:

abstract class AbstractClass
{
    internal abstract void Test();
}

sealed class DerivedClass : AbstractClass
{        
    internal override void Test()
    {
        Console.WriteLine("In override DerivedClass.Test() method");
    }

    internal void Test(int a = 1)
    {
        Console.WriteLine("In DerivedClass.Test(int a=1) method " + a);
    }

    internal void Test(int b, int a = 1)
    {
        Console.WriteLine("In DerivedClass.Test(int b, int a=1) method " + string.Format("{0} {1}", b, a));
    }
}

This is how I called Test() method:

   DerivedClass d = new DerivedClass();       
   d.Test();
   d.Test(6);
   d.Test(b:7);

Output :

In DerivedClass.Test(int a=1) method 1

In DerivedClass.Test(int a=1) method 6

In DerivedClass.Test(int b, int a=1) method 7 1

Regarding d.Test();: Here my understanding is, it will treat Test() as method with an optional parameter, and will invoke Test(int a = 1) with this output:

In DerivedClass.Test(int a=1) method 1

But this is what confuses me when executing d.Test(6);: Why this method call isn't giving output as:

In DerivedClass.Test(int b, int a=1) method 6 1

As per my understanding "6" is the mandatory parameter and it should invoke

internal void Test(int b, int a = 1)

Kindly explain what is wrong with my understanding.

Also how to call an overriden method?

internal override void Test()
2

There are 2 answers

1
David Arno On

The rules around optional parameters can be a little confusing, but a simple rule of thumb to remember is that it'll always use a method with less parameters in preference to one with more.

So for

d.Test(6);

the method with just one parameter:

internal void Test(int a = 1)

will be used, even though it's an optional parameter.

0
Patrick Hofman On

The rule matching for internal void Test(int a = 1) matches your code d.Test(6); best: it matches on the number of arguments, the types. That makes the method the best match.

When calling d.Test(b:7);, you force it to run as the last method, since you are matching on the name of the parameter. That makes the last method the best matching.

The first (d.Test();) doesn't match on the method you expected (void Test()), since 'own' methods are preferred over derived methods. Try to remove the base class or use the new operator on the method and you will see.