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类内部获得。