簡體   English   中英

C#繼承隱藏繼承的成員

[英]C# Inheritance to hide inherited Members

我看了其他線程像這樣 ,但他們並沒有為我工作。

我有兩節課:

public class ClassA 
{
    public string _shouldBeInteger;
    public string _shouldBeBool;
    public string _shouldBeDateTime;
}

public class ClassB : ClassA
{
   public int? shouldBeInteger
    {
        get { return (_shouldBeInteger != null) ? Convert.ToInt32(Convert.ToDouble(_shouldBeInteger)) : new int?(); }
        set { _shouldBeInteger = Convert.ToString(value); }
    } 

  //... same thing with datetime etc.


}

如果我現在創建一個ClassB的新對象,我得到

 _shouldBeInteger, _shouldBeBool, _shouldBeDateTime;
 shouldBeInteger,shouldBeBool,shouldBeDateTime

但我想隱藏_variables給用戶。 在ClassB中將它們設置為私有將覆蓋它們,但我需要訪問它們才能解析字符串值。

更新

有一個ClassC填充ClassAs的值,這主要是它們必須可寫的原因。 我沒有辦法改變它的工作方式,但我完全控制了ClassA和ClassB

ClassC //not changeAble for me
{
 //infomagic filling values of ClassA    
}

將ClassA變量設置為private將不起作用,因為ClassA的程序員以一種奇怪的方式生成它。

因為ClassA需要是可寫的,但是對於繼承的其他類不可讀,我終於得到了這個:

ClassA 
{ 
  public string _shouldBeInteger { protected get; set; } 
  //and so on
} 

這會導致ClassB與theese屬性一起使用,而不會將它們放在外面。 Intellisense仍會顯示它們,但您可以考慮使用:

 [EditorBrowsable(EditorBrowsableState.Never)]

解決這個問題。

謝謝大家。

我認為您可以使用以下方法解決問題:

public class ClassA 
{
    protected string _shouldBeInteger;
    protected string _shouldBeBool;
    protected string _shouldBeDateTime;
}

所以這些變量可以被派生類訪問,但不能訪問用戶。

用戶更新后編輯:
我不知道這對你來說是否是一個vali解決方案,但請嘗試:

public class ClassB : ClassA
{
    public new int? _shouldBeInteger
    {
        get { return (base._shouldBeInteger != null) ?
                     Convert.ToInt32(Convert.ToDouble(base._shouldBeInteger)) : 
                     new int?(); }
        set { base._shouldBeInteger = Convert.ToString(value); }
    }
}

繼承不能像你想象的那樣隱藏成員。 new修飾符用於“隱藏”基礎成員,但在與基本類型交談時不會很好。

http://msdn.microsoft.com/en-us/library/435f1dw2.aspx

您可以更改字段的訪問級別(首選方式),也可以包裝類而不是繼承它,並提供簡單的傳遞方法來委托包裝類。 這稱為適配器模式

public class ClassB
{
    private ClassA _wrappedClass;
}

另外,您的公共字段遵循通常用於私有字段的命名約定。

派生類所需的訪問級別protected 如果成員是公開使用但在同一個程序集中,則可以使用protected internal 如果成員被其他程序集公開使用......我建議重構。

問題是您在基類中聲明了字段public。 為了不違反繼承的多態性,基類中的任何公共事物也必須在所有派生類中都是公共的。 如果你可以改變它,你永遠不能確定ClassB可以傳遞給期望ClassA的東西。

因此,正如其他人所建議的那樣,您可能希望將基類字段聲明為protected,這類似於private,但派生類可以看到它們。

但是,如果您確實需要通過ClassA的實際實例訪問它們,則可以將它們聲明為private,並為它們提供虛擬公共屬性,然后派生類可以覆蓋它們。 這至少允許派生類改變它們的行為,但它實際上仍然無法隱藏它們。

如果這也不適合,那么可能值得考慮使用組合而不是繼承,因為替換原則實際上妨礙了你的方式,這是繼承的基礎。

如果您無法控制ClassA,則需要創建一個包裝器/適配器類,如下所示:

public class ClassB
{
    private readonly _classA = new ClassA();

    public int? shouldBeInteger
    {
        get
        {
            return (this._classA._shouldBeInteger != null)
                ? Convert.ToInt32(Convert.ToDouble(this._classA._shouldBeInteger))
                : new int?();
       }
        set
        {
            this._classA._shouldBeInteger = Convert.ToString(value);
        }
    } 
}
public class ClassB
{
    private int shouldBeInteger;

    public int ShouldBeInteger
    {
        get { return shouldBeInteger; }
        set { shouldBeInteger = value; }
    }

}

要么

  public class ClassB
  {

    public int ShouldBeInteger{ get; set; }

  }

在這兩種情況下,ShouldBeInteger都可以在課外訪問。

在第一種情況下,有一個私人領域,在課外無法訪問,

私人領域的價值可以通過公共領域設定。

在第二種情況下,編譯器會自動創建一個私有支持字段並執行相同操作

過程如上。 這是自動實現的屬性。

希望這可以幫到你。

暫無
暫無

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

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