簡體   English   中英

在派生類中重載基方法

[英]Overloading base method in derived class

所以我正在玩C#以查看它是否與此帖子中的C ++行為相符: http//herbsutter.com/2013/05/22/gotw-5-solution-overriding-virtual-functions/當我遇到這個非常奇怪的時候行為:

public class BaseClass
{
    public virtual void Foo(int i)
    {
        Console.WriteLine("Called Foo(int): " + i);
    }

    public void Foo(string i)
    {
        Console.WriteLine("Called Foo(string): " + i);
    }
}

public class DerivedClass : BaseClass
{
    public void Foo(double i)
    {
        Console.WriteLine("Called Foo(double): " + i);
    }
}

public class OverriddenDerivedClass : BaseClass
{
    public override void Foo(int i)
    {
        base.Foo(i);
    }

    public void Foo(double i)
    {
        Console.WriteLine("Called Foo(double): " + i);
    }
}

class Program
{
    static void Main(string[] args)
    {
        DerivedClass derived = new DerivedClass();
        OverriddenDerivedClass overridedDerived = new OverriddenDerivedClass();

        int i = 1;
        double d = 2.0;
        string s = "hi";

        derived.Foo(i);
        derived.Foo(d);
        derived.Foo(s);

        overridedDerived.Foo(i);
        overridedDerived.Foo(d);
        overridedDerived.Foo(s);
    }
}

產量

Called Foo(double): 1
Called Foo(double): 2
Called Foo(string): hi
Called Foo(double): 1
Called Foo(double): 2
Called Foo(string): hi

所以顯然它傾向於隱式轉換的int,以便從基類中更加特定的Foo(int)加倍。 或者它是否隱藏了基類的Foo(int)? 但那么:為什么不隱藏Foo(字符串)? 感覺非常不一致...如果我重寫Foo(int)也沒關系; 結果是一樣的。 誰能解釋一下這里發生了什么?

(是的,我知道在派生類中重載基本方法是不好的做法--Liskov和所有 - 但我仍然不會指望OverriddenDerivedClass中的Foo(int)沒有被調用?!)

要解釋它對OverriddenDerivedClass示例的工作原理:

在這里查看成員查找的C#規范: http//msdn.microsoft.com/en-us/library/aa691331%28VS.71%29.aspx

這定義了查找的完成方式。

特別是,看看這部分:

首先,構造在T中聲明的名為N的所有可訪問(第3.5節)成員的集合,並構造T的基本類型(第7.3.1節)。 包含覆蓋修飾符的聲明將從集合中排除。

在你的情況下, NFoo() 由於Declarations that include an override modifier are excluded from the setDeclarations that include an override modifier are excluded from the set因此override Foo(int i)將從集合中排除。

因此,只有非重寫的Foo(double i)仍然存在,因此它是被調用的那個。

這就是它對OverriddenDerivedClass示例的工作原理,但這不是DerivedClass示例的解釋。

要解釋一下,請看一下規范的這一部分:

接下來,從集合中刪除被其他成員隱藏的成員。

DerivedClassFoo(double i)Foo(int i)隱藏在基類中,因此它將從集合中刪除。

這里的棘手問題是:

在集合中刪除與基本類型S中聲明的M具有相同簽名的所有方法。

你可能會說“但是等等! Foo(double i)Foo(int i) 沒有相同的簽名,因此它不應該從集合中刪除!”。

然而,因為有從int加倍的隱式轉換,它認為具有相同的簽名,所以Foo(int i) 集合中移除。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM