Can you explain me this strange behaviour of c# wi

2020-06-01 01:27发布

问题:

This question already has answers here:
Closed 8 years ago.

Possible Duplicate:
C# optional parameters on overridden methods

This is the output of the following code:

Peter: -1
Peter: 0
Fred: 1
Fred: 1

Can you explain me why the call of Peter p.TellYourAge() and p.DoSomething() is not identical?

Here the code to try it yourself (VS2010 and FW 4):

    static void Main(string[] args)
    {
        Peter p = new Peter();
        p.TellYourAge(); // expected -1, result: -1
        p.DoSomething(); // expected -1, result: 0

        Fred f = new Fred();
        f.TellYourAge(1); // expected 1, result: 1
        f.DoSomething(); // expected 1, result: 1

        Console.ReadKey();
    }
}

public abstract class Person
{
    public abstract void TellYourAge(int age); // abstract method without default value
}

public class Peter : Person
{
    public override void TellYourAge(int age = -1) // override with default value
    {
        Console.WriteLine("Peter: " + age);
    }

    public void DoSomething()
    {
        TellYourAge();
    }
}

public class Fred : Person
{
    public override void TellYourAge(int age) // override without default value
    {
        Console.WriteLine("Fred: " + age);
    }

    public void DoSomething()
    {
        TellYourAge(1);
    }
}

回答1:

If you happen to use Resharper, it will give you the following warning / notification.

"Optional parameter default value differs from parameter age in base method void TellYourAge(int age)."

Look out when you mix optional parameter values and inheritance. Default parameter values are resolved at compile time, not runtime. The default belongs to the reference type being called. Here it resolves to the Person type and it uses the default value of an integer which is 0, instead of -1.

You can find some information about common pitfalls regarding optional parameters here:

http://geekswithblogs.net/BlackRabbitCoder/archive/2010/06/17/c-optional-parameters---pros-and-pitfalls.aspx

Easy fix if you want to use it this way. Explicitly specify the keyword 'this' when calling the method TellYourAge. This way the desired default value will be determined at compile time.

public void DoSomething()
{
    this.TellYourAge();
}