当存在具有可选参数的重载时,编译器如何选择重载

时间:2017-08-23 17:51:14

标签: c# recursion override optional-parameters

我不明白如果存在可选参数,编译器如何决定调用哪个重载。在MSDN我找到:

  

如果两名候选人被判断为同样好,则优先选择a   候选者没有可选参数的参数   在通话中被省略了。这是一般的结果   对于拥有较少的候选人,重载决议的偏好   参数。

考虑这个基类及其派生类:

public class FooBase {
    public virtual void Foo() { }
}

public class NonRecursiveFoo : FooBase {
    public override void Foo() {
        Foo();
    }

    public void Foo(string fooBar = null) {
        throw new NotImplementedException();
    }
}

现在通过调用Foo()中的NonRecursiveFoo.Foo()执行哪个方法?

我希望它是对自己的递归调用,但它不是。它实际上会使用可选参数调用重载。我认为大多数程序员都希望这个调用是递归的。

即使我从NonRecursiveFoo继承并尝试进行递归调用,它也不会是递归的:

public class StillNotRecursiveFoo : NonRecursiveFoo {
    public override void Foo() {
        Foo();
    }
}

Foo()调用也会使用可选参数调用NonRecursiveFoo中的重载。

如果我只有一个包含两个这样重载的类,调用Foo()将调用不带参数的重载,而不是带有默认参数的重载。这是我期望的行为(以及MSDN似乎在说什么)。

public class FooAlone {
    public void Foo() {
        Foo();
    }

    public void Foo(string fooBar = null) {
        throw new NotImplementedException();
    }
}

我不明白这是如何运作的。我甚至想知道如果事实上我想要执行递归调用我必须做什么。

我也想知道利用这种行为是不好的设计。是否可以使用默认参数进行重载,并在没有参数的情况下从重写方法调用它?

最后,这意味着您可以在不使用new关键字且没有任何编译器警告的情况下隐藏非虚方法。

public class BarBase {
    public void Foo() { }
}

public class Bar : BarBase {
    public void Foo(string fooBar = null) { }
}

0 个答案:

没有答案