2012-12-17 57 views
4

[編輯]改寫從明確實現一個接口

基類的方法。由於多了幾分複雜性比需要在原來的職位 - 我的that--道歉,我會盡力和簡化的東西一點點。

本來我有一個基類,看起來像這樣:

public class OurViewModel 
{ 
    public bool Validate(ModelStateDictionary modelState){...} 
} 

我的類繼承,並隱藏了方法,使用new關鍵字:

public class MyViewModel : OurViewModel 
{ 
    public new bool Validate(ModelStateDictionary modelState) {...} 
} 

同時,IValidatableObject接口已經出現:

public interface IValidatableObject 
{ 
    IEnumerable<ValidationResult> Validate(ValidationContext validationContext); 
} 

現在,OurViewModel也(可惜)也被改變了。它看起來像這樣:

public class OurViewModel : IValidatableObject 
{ 
    IEnumerable<ValidationResult> IValidatableObject.Validate(ValidationContext validationContext) {..} 
} 

我現在需要做什麼又是隱藏的驗證方法MyViewModel,但我無法弄清楚如何做到這一點與目前的安排。有沒有很好的方法來解決這個問題?

(FWIW,我同意增加一個新的接口基類是不應該做的事情的最佳方式,但它是怎麼在這裏發生的事情。)


[原帖]

我無法在我的一個類中重寫某個方法。有人改從這個基類的繼承模型:

public class OurViewModel : IntlViewModelBase<OurResources> 

這樣:

public class OurViewModel : IntlViewModelBase<OurResources>, IValidatableObject 

IValidatableObject有一個單一的方法簽名,Validate()

IEnumerable<ValidationResult> Validate(ValidationContext validationContext); 

OurViewModel了驗證方法看起來像:

public bool Validate(ModelStateDictionary modelState) 

...現在是該改變後:

IEnumerable<ValidationResult> IValidatableObject.Validate(ValidationContext validationContext) 

我的課,同時,從OurViewModel繼承。它使用new關鍵字來實現它自己的驗證布爾版本。

看來我不能再隱藏Validate方法,因爲我的類沒有實現IValidatableObject。現在對我來說重寫這種方法的正確方法是什麼?

+2

看起來你不能覆蓋該方法。它不是「虛擬」的。 –

+0

我在我的方法中使用了'new'關鍵字來暗示我自己的版本 - 也許我不應該在我的描述中使用'override'這個詞。這次我似乎無法使用'new',所以這聽起來像我必須使基本方法變爲虛擬? – larryq

+0

@larryq所以你想使用'IValidatableObject'的'Validate'的基類的實現,還是你想使用你自己的?另外,你是否有權修改基類? – Servy

回答

0

我可能完全錯過了這一點,但這個編譯罰款給我(使​​用存根類爲OurResourcesIntlViewModelBase<T>)。

public class OurViewModel : IntlViewModelBase<OurResources>, IValidatableObject 
{ 
    public bool Validate(ModelStateDictionary modelState) 
    { 
     throw new NotImplementedException(); 
    } 

    IEnumerable<ValidationResult> IValidatableObject.Validate(ValidationContext validationContext) 
    { 
     throw new NotImplementedException(); 
    } 
} 

public class MyViewModel : OurViewModel 
{ 
    public new bool Validate(ModelStateDictionary modelState) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+0

伊芙......你有什麼將不會工作..他需要添加虛擬關鍵字.. – MethodMan

+0

我可能沒有在我的原始文章中清楚。對於那個很抱歉。發生的事情是,Validate的bool版本現在已經消失,取而代之的是它的IValidateableObject.Validate版本。 – larryq

+0

@larryq那麼你不需要在子對象上使用'new',因爲它沒有任何影子的方法。你還沒有真正描述你需要做什麼,那麼目前沒有工作。 – Servy

0

如果您想覆蓋新的Validate方法(IValidatableObject.Validate),則只需添加virtual關鍵字即可。

public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
+0

編譯器告訴我'虛擬'對顯式接口實現無效。 – larryq

+0

將虛擬添加到您的基類OurViewModel中的方法。 –

+0

我明白你在說什麼。它需要明確嗎? (例如,你是否可以在OurViewModel中聲明這個方法,如下所示:「public virtual IEnumerable Validate(ValidationContext validationContext)」) –

0

我想我已經夠了被改寫的這個問題,並已決定與這裏 - 提供this one

謝謝大家誰回答一個簡單的版本,再試一次。管理員可以關閉此主題,或者將其鏈接到新問題?我不確定這種情況下SO的網絡禮儀是什麼。

+0

你可以編輯問題本身(否?) – Dhananjay

0

幾件事情:

1.

如果你想在派生類中新 實施的基礎類的每個方法再有就是從基地獲得 沒有意義的。繼承的主要目的是代碼重用。所以你可以簡單地從父母子女中刪除關係。

2.

讓我們假設,在你的基類有一些方法被 實際上繼承。在這種情況下,我不應該有一個 標記基類的接口成員與虛擬 關鍵字和派生類稱它是新的。

-

如果你問即將實施這一局面則 我們需要知道什麼是你的目標不同的方式。如果目標是派生成員 有新的定義,那麼更好的方法是明確的 在派生類中的接口的實現。

請提一下您面臨的確切問題?難道你不能使用新的關鍵字,或者你正在尋求不同的方法來解決這種情況。

+0

繼承的主要「正確」用法是可替代性。對於代碼重用,封裝通常更好。 – supercat

+0

對於我來說,替代性意味着獅子應該能夠被當作動物來對待,我們可以繞過動物對象而不用擔心實際的類型在裏面......它的真實性在於可替代性是繼承的重要用法,但是這個概念的名稱本來是替代而不是繼承。繼承意味着派生的人可以使用基礎成員函數..ie。他們繼承它。 – Dhananjay

+0

繼承提供了代碼重用和可替代性。在只有一個*需要代碼重用的情況下,封裝通常更好。在任何可替代的東西都不需要重用任何實現細節的情況下,接口通常比抽象類更好。我的觀點是,如果想要將一種類型的實例提供給需要另一種類型的代碼的實例,這是一個好兆頭,即前者類型應該從後者繼承*,即使它取代了每個成員*。 – supercat