[英]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.