正如每個人都知道在類中使用virtual關鍵字允許我們在其派生的子類中覆蓋它。然而,方法仍然必須堅持相同的簽名,例如返回值,參數等。使用虛擬覆蓋方法簽名
問題:在C#中,我怎樣才能重寫簽名呢?這可能嗎?
謝謝。
正如每個人都知道在類中使用virtual關鍵字允許我們在其派生的子類中覆蓋它。然而,方法仍然必須堅持相同的簽名,例如返回值,參數等。使用虛擬覆蓋方法簽名
問題:在C#中,我怎樣才能重寫簽名呢?這可能嗎?
謝謝。
這是不可能的。如果你需要的話,你可以創建一個重載。
編輯
爲了使我的情況下對new
,請考慮一下,你有一個基本對象的情況下,和一個從它繼承。通過在您試圖「更改」方法簽名的方法之前放置new
,您實際上正在浪費四個關鍵筆劃。現在
public class Base {
public string Foo() { return null; }
}
public class Inherited : Base {
public new int Foo() { return 0; }
}
,Inherited
有兩種方法:
public string Foo() { return null; }
public int Foo() { return 0; }
你實際上並沒有改變的方法簽名。因此,關鍵字new
甚至不需要。你會得到同樣的效果沒有它:
public class Inherited : Base {
public int Foo() { return 0; }
}
採用new
是override a non-virtual member of a base class:
public class Base {
public string Foo() { return null; }
}
public class Inherited : Base {
public new string Foo() { return "Something else..."; }
}
但是你會遇到這個問題,如果你沒有注意這個微妙。通過virtual
,您可以獲得一個虛擬查找表,將您的功能映射到正確的呼叫。用new
,你不會。如果您通過Inherited
需要Base
對象(當然這會起作用),Base
類的Foo()
將被調用!不,Inherited
「覆蓋」Foo()
。
這與重寫虛擬成員的行爲不同。
public static class MyClass {
public string MyMethod (Base @base) {
return @base.Foo();
}
}
[Test]
public void then_it_should_return_non_null() {
var obj = new Inherited();
var result = MyClass.MyMethod(obj); // obj will get upcasted to Base
Assert.That (result, Is.EqualTo(obj.Foo())); // Assert fails!
}
[Test]
public void inherited_should_return_correct_value()
{
var obj = new Inherited();
var result = obj.Foo(); // will access the "new" method, hiding Base's implementation
Assert.That (result, Is.Not.Null); // Assert passes!
}
您可以用new
關鍵字隱藏舊的實現。但是,基類將無法看到它。
class Base {
public string Foo() { }
}
class Sub : Base {
new public int Foo() { }
}
new
只在呼叫簽名相同時才需要。
到那時,你只是在做一個新的方法。但是,如果你想簡單地用新方法簽名創建一個新方法,然後調用base.OtherMethod(param1,param2)...你可以。
我想說明的一點是,如果你打算創建具有相同名稱的一種方法,在基類,但有一個不同的簽名但你還是想僅僅調用基類,然後你可以。
例如:
// In base class - note, the "virtual" isn't necessary.
public virtual void PostMessage(string message, DateTime entryDate) { ... }
那你認爲......「哦,我想這個基類曾經對自己沒有要求的日期是方法的重載......我該怎麼辦? !」
// In your sub-class.
public void PostMessage(string message)
{
base.PostMessage(message, DateTime.Now);
}
感謝您的評論。我看到你在說什麼,但沒有得到最後的聲明「,然後調用base.OtherMethod(param1,param2)...你可以。」你能給我一些想法嗎? –
我會編輯答案更清晰。 –
您正在討論創建新方法。如果名稱相同,但參數不同(返回類型和參數的類型和參數數量),則實際上會超載。
雖然這並不會改變簽名。 –
@ JamesD'Angelo是的,它可以改變簽名。 –
@ JamesD'Angelo http://msdn.microsoft.com/en-us/library/435f1dw2.aspx –