2013-11-28 95 views
2

我有這樣一個類:爲什麼派生類無法從基類訪問受保護的getter?

public class Base 
{ 
    public Base(string name) 
    { 
     this.Name = name; 
    } 

    public string Name { get; set; } 
    public string PrettyName 
    { 
     get { return Prettify(Name); } 
    } 
} 

,我從中獲得:

public class Derived : Base 
{ 
    public Derived(Base b) : base(b.Name) { } 
} 

Name屬性不應訪問;邏輯名稱只能由PrettyName訪問。所以我想我會做這樣的屬性:

public string Name { protected get; set; } 

但我發現了這一點:

Cannot access protected member 'Name' via a qualifier of type 'Base'; the qualifier must be of type 'Derived' (or derived from it) 

這是爲什麼? getter應該暴露給基類和它的所有子類。我在這裏弄錯了什麼?

回答

5

getter應暴露給基類和它的所有子類。

不,不是。這不是自動執行的屬性的問題 - 這是什麼protected意味着什麼。

訪問子類中的受保護成員必須通過該子類(或其他子類)的實例。您無法使用Base.Name代替任意代碼Base代碼Derived

從C#規範的3.5.3節:

protected實例成員,其中它被聲明的類的程序文本,並且當外部訪問的protected internal實例成員外的訪問在聲明程序的程序文本時,訪問必須在派生於聲明類的類聲明中進行。此外,訪問需要通過派生類類型的實例或由它構造的類類型來實現。此限制可防止一個派生類訪問其他派生類的protected成員,即使成員是從相同的基類繼承的。

一個簡單的解決辦法是重載構造函數Base

protected Base(Base b) : this(b.Name) 
{ 
} 

然後在Derived

public Derived(Base b) : base(b) { } 

在這一點上,可以使Name二傳手私人,太 - 或更好,使其完全只讀:

private readonly string name; 
public string Name { get { return name; } } 
0

這是製作派生構造函數的一種奇怪的方式。爲什麼不是:

public class Derived : Base 
{ 
    public Derived(string name) : base(name) 
    { } 

    public void Test() 
    { 
     //here, it's perfectly ok to access the protected Name. 
    } 
} 
+0

因爲示例代碼是簡化的,我試圖用真正的代碼實現的是將'b'的所有屬性(不止是名稱)複製到新對象。 –

相關問題