11

I wrote the following code:

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

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

Now, in VS2010 it results in the following compilation error:

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

This seems quite illogical to me - why can't I access the protected field of the class instance from a method of the class, which is derived from it?

So, why does this happen?


Found a strict answer - http://blogs.msdn.com/b/ericlippert/archive/2005/11/09/491031.aspx

Yippie-Ki-Yay
  • 22,026
  • 26
  • 90
  • 148
  • 1
    +1 for a very clearly written question. :) – Almo May 18 '12 at 18:05
  • What you can do is create a protected static method that provides access only to a derived class, like so: public class A { protected string Howdy = "Howdy!"; } public class B : A { public void CallHowdy() { A a = new A(); Console.WriteLine(a.Howdy); } } – Michael Erickson Jan 11 '15 at 00:53

4 Answers4

7

You're not accessing it from inside the class, you're trying to access the variable as though it were public. You would not expect this to compile, and this is pretty much what you are trying to do:

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

There is no relationship, and it sounds like you are confused why that field is not public.

Now, you could do this, if you wanted to:

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

Because B has inherited the data from A in this instance.

Tejs
  • 40,736
  • 10
  • 68
  • 86
  • Well, actually, I was confused by the possibility to do that in `PHP5` (I also asked this question: http://stackoverflow.com/questions/10653991/php5-member-visibility). Difference like this should probably have a strong reason behind it, don't you think so? – Yippie-Ki-Yay May 18 '12 at 18:19
  • Well, PHP seems to be the odd one there, as it seems to be exposing a protected variable illegally. There are more strict type boundaries than PHP in C# it seems. – Tejs May 18 '12 at 18:21
  • I am also confused by the fact that everyone in the corresponding `PHP` question keeps telling me things like *"Why shouldn't it be accessible? That's perfectly valid".* I guess this question is more about certain coding habits. – Yippie-Ki-Yay May 18 '12 at 18:28
  • `B` has access to the protected data of it's _own instance_, not to the values of _other instances_. – Tejs May 18 '12 at 18:31
3

You could do

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

In your code, you're trying to access Howdy from outside an A, not from within a B. Here, you are inside a B, and can therefore access the protected member in A.

Almo
  • 15,538
  • 13
  • 67
  • 95
1

A protected member of a base class is accessible in a derived class only if the access takes place through the derived class type.

You are getting error because because A is not derived from B.

http://msdn.microsoft.com/en-us/library/bcd5672a(v=vs.90).aspx

DotNetUser
  • 6,494
  • 1
  • 25
  • 27
0

A protected member is only visible to itself and derived members. In your case, the declaration of A implies that only public members are accessible, just as if you instantiated an A from any other class. You could, however, simply write this.Howdy, because, due to the derivation chain, Howdy is available from inside of class B.

Maciej
  • 2,175
  • 1
  • 18
  • 29