簡體   English   中英

對象繼承,密封方法覆蓋和C#

[英]Object Inheritance, Sealed Method Overrides, and C#

我有一個由另一個程序集定義的抽象類(不可編輯):

public abstract class A
{
    public void Run()
    {
        Go("Hello World");
    }

    protected virtual void Go(string message)
    {
        // Do Nothing
    }
}

現在我有一個我想從這個實現Go()的類繼承的庫。 這里的訣竅是我不希望任何繼承自我的人能夠覆蓋我的Go()實現,但我也不想以任何方式更改簽名。 我實際上希望調用這兩個實現。 這是我到目前為止所得到的:

public abstract class B_Intercept : A
{
    protected sealed override void Go(string message)
    {
        Console.WriteLine(message);
        Go_Impl(message);
    }

    internal abstract void Go_Impl(string message);
}

public abstract class B : B_Intercept
{
    protected new virtual void Go(string message)
    {
    }

    internal override void Go_Impl(string message)
    {
        Go(message);
    }
}

現在我的最終用戶可以將他們的類繼承從A切換到B而不起作用(除了我的Console.WriteLine)。

public class C : A // This can be changed to B with no other edits
{
    protected override Go(string message)
    {
        // Do stuff
    }
}

現在,原始庫可以被賦予C的實例,它將被裝箱為A,原始庫將調用Run()。 Run將使用B_Intercept的Go(),它將消息轉儲到控制台,然后調用Go_Impl()。 Go_Impl將在B中運行,它將調用B的Go(),它可以被C覆蓋。

這感覺非常迂回。

這些方法的一些安全性還有一個額外的好處(它們不能直接調用Go_Impl),但仍有漏洞(它們可以調用base.Go)。 我認為這些漏洞可以用第三層封閉,但我還沒試過,坦白說我認為這有點荒謬。 但它仍然感覺像很多樣板代碼。 B_Intercept還有一個蹩腳的副作用,需要公開而不是內部,這會以一種無法解釋的方式提升我的圖書館的表面區域。

有更簡單,更安全的方式嗎?

這里的問題是你正在嘗試做一些不是原始類開發人員的意圖。

Go已作為virtual方法提供,現在您正在嘗試隱藏它,同時希望將其保持為OO盡可能 - ( 更新 )而不僅僅是,您還關注繼承類調用基本方法。 我真誠地祝賀你的努力,關心和關注,但有些事情必須給予

要么你必須使用composition包裝的A類,並提供了你打算提供,適合你的設計的接口, 或者你必須使用inheritance和接受其短到來,主要是從事實出現你真的改變預期的行為班級。 對於我的兩分錢,我會選擇第一個選項: composition 在一天結束時,這正是你想要實現的目標。

暫無
暫無

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

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