[英]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節)。 包含覆蓋修飾符的聲明將從集合中排除。
在你的情況下, N
是Foo()
。 由於Declarations that include an override modifier are excluded from the set
的Declarations that include an override modifier are excluded from the set
因此override Foo(int i)
將從集合中排除。
因此,只有非重寫的Foo(double i)
仍然存在,因此它是被調用的那個。
這就是它對OverriddenDerivedClass
示例的工作原理,但這不是DerivedClass
示例的解釋。
要解釋一下,請看一下規范的這一部分:
接下來,從集合中刪除被其他成員隱藏的成員。
DerivedClass
的Foo(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.