2012-05-18 123 views
9

我寫了下面的代碼:C#在派生類中訪問受保護的成員

public class A        
{ 
    protected string Howdy = "Howdy!";  
} 

public class B : A       
{ 
    public void CallHowdy() 
    { 
     A a = new A(); 
     Console.WriteLine(a.Howdy); 
    } 
} 

現在,VS2010這將導致以下編譯錯誤:

Cannot access protected member 'A.a' via a qualifier of type 'A'; the qualifier must be of type 'B' (or derived from it).

這似乎不合情理我 - 爲什麼我不能從類派生的類的方法訪問類實例的protected字段?

那麼,爲什麼會發生這種情況


發現了一個嚴格的答案 - http://blogs.msdn.com/b/ericlippert/archive/2005/11/09/491031.aspx

+1

+1對於一個非常清晰的問題。 :) – Almo

+0

你可以做的是創建一個受保護的靜態方法,只提供對派生類的訪問,如下所示: public class A { protected string Howdy =「Howdy!」; } 公共類B: { 公共無效CallHowdy() { 甲一個新= A(); Console.WriteLine(a。你好); } } –

回答

7

你沒有從課堂內部訪問它,你試圖訪問該變量,就好像它是public。你不會想到這來編譯,這是一個很值得你正在嘗試做的事:

public class SomethingElse 
{ 
    public void CallHowdy() 
    { 
     A a = new A(); 
     Console.WriteLine(a.Howdy); 
    } 
} 

沒有關係,這聽起來像你是困惑,爲什麼那場是不公開的。現在

,你可以這樣做,如果你想:

public class B : A 
{ 
    public void CallHowdy() 
    { 
     Console.Writeline(Howdy); 
    } 
} 

因爲B繼承了數據從A在這種情況下。

+0

嗯,實際上,我對PHP5中做這件事的可能性感到困惑(我也問過這個問題:http://stackoverflow.com/questions/10653991/php5-member-visibility)。像這樣的差異應該有一個強有力的理由,你不這麼認爲嗎? –

+0

那麼,PHP似乎是一個奇怪的,因爲它似乎是非法暴露一個受保護的變量。看起來C#中有比PHP更嚴格的類型邊界。 – Tejs

+0

我也對這樣的事實感到困惑,在相應的'PHP'問題中,每個人都會一直告訴我諸如*「爲什麼不能訪問?這非常有效」。*我想這個問題更多的是關於某些編碼習慣。 –

3

你可以做

public class B : A       
{ 
    public void CallHowdy() 
    { 
     Console.WriteLine(Howdy); 
    } 
} 

在你的代碼,你想從訪問你好一個A外,沒有從B內部這裏,你在B裏面,因此可以訪問A中的受保護成員。

0

被保護的成員得到的僅僅是看到自己和派生成員。就你而言,A的聲明意味着只有公共成員是可訪問的,就像你從任何其他類中實例化A一樣。但是,你可以簡單地寫這個。因爲,由於推導鏈,Howdy可以從B類內部獲得。