From: JAM on
I thought this should work:

class A
{
protected void F();
}

class B : A
{
public List<A> items;

public void B()
{
items[0].F();
}
}

The idea was not to expose function F outside of class A but still
make it visible to B. But if A is just and item in some list that is
part of B, the compiler complains about access to F :-(
Do I have to expose F as public to be able to access it when
particular A is not a base for this particular B but when the A
belongs somehow to this particular B which has some different A as
base ?

JAM
From: Arne Vajhøj on
On 31-01-2010 21:34, JAM wrote:
> I thought this should work:
>
> class A
> {
> protected void F();
> }
>
> class B : A
> {
> public List<A> items;
>
> public void B()
> {
> items[0].F();
> }
> }
>
> The idea was not to expose function F outside of class A but still
> make it visible to B. But if A is just and item in some list that is
> part of B, the compiler complains about access to F :-(
> Do I have to expose F as public to be able to access it when
> particular A is not a base for this particular B but when the A
> belongs somehow to this particular B which has some different A as
> base ?

Two ideas:

1) Put the stuff in same assembly and use internal visibility.

2) If they can not be put in same assembly then still make
it internal and use the InternalsVisibleTo attribute to
make it work.

Not a pure solution, but maybe it is a practical solution for you.

Arne
From: Peter Duniho on
JAM wrote:
> I thought this should work:
>
> class A
> {
> protected void F();
> }
>
> class B : A
> {
> public List<A> items;
>
> public void B()
> {
> items[0].F();
> }
> }
>
> The idea was not to expose function F outside of class A but still
> make it visible to B. But if A is just and item in some list that is
> part of B, the compiler complains about access to F :-(

That's correct. To access a protected member of a base class, your
class has to access that protected member via a variable of its own type.

Consider the alternative: if you could start accessing protected members
of _any_ instance of a class A just by inheriting A and doing it from
the sub-class, then accessibility protection would be basically
meaningless. You could bypass it anytime you want just by inheriting
the class you want to get at.

Note that if your "items" variable was a "List<B>", the access would
have been just fine. That's because the class B is trusted to access
protected members in instances of itself.

From the C# 3.0 specification:

When a protected instance member is accessed outside
the program text of the class in which it is declared,
and when a protected internal instance member is
accessed outside the program text of the program in
which it is declared, the access must take place within
a class declaration that derives from the class in which
it is declared. Furthermore, the access is required to
take place through an instance of that derived class type
or a class type constructed from it. This restriction
prevents one derived class from accessing protected members
of other derived classes, even when the members are
inherited from the same base class.

> Do I have to expose F as public to be able to access it when
> particular A is not a base for this particular B but when the A
> belongs somehow to this particular B which has some different A as
> base ?

That sentence is pretty awkward. I'm not sure it means what you meant
it to mean. But, if you're asking if you _have_ to use "public" to
write code in one type B that can access non-public members in a base
type A of that type B but without the compiler being able to verify that
the instance is in fact an instance of type B, strictly speaking the
answer is "no". An alternative to "public" that doesn't have the same
restriction as "protected" is "internal". But that only works if the
code is in the same assembly).

But as a general rule, yes�if you have a member in one class that you
want to be accessible via code not in an instance of the class in which
the member is defined, that member has to be public.

I would furthermore argue that if you find yourself trying to design a
class to the contrary of this, that you've made a mistake in the program
design. The accessibility rules are there for a reason, and even
"internal" should IMHO be used VERY sparingly. Any time you find
yourself trying to get around the given accessibility rules, it suggests
that you're leaking implementation details in a way that would negate
the benefit of abstracting your types in the first place.

Pete
From: Angel J. Hernandez M. on
Hey mate, quick question... What would you want to do it like that? :-|

If you want to get access mark it as internal but it's a code a bit
"difficult" and odd to read/understand

Regards,


--
Angel J. Hernandez M.
MCP,MCAD,MCSD,MCDBA
Microsoft MVP

http://twitter.com/angeljesus14
http://msmvps.com/blogs/angelhernandez

"JAM" <ja_1410(a)yahoo.com> wrote in message
news:43f4856d-3a54-43a3-9f4a-e6a6cf8687ee(a)b36g2000yqn.googlegroups.com...
> I thought this should work:
>
> class A
> {
> protected void F();
> }
>
> class B : A
> {
> public List<A> items;
>
> public void B()
> {
> items[0].F();
> }
> }
>
> The idea was not to expose function F outside of class A but still
> make it visible to B. But if A is just and item in some list that is
> part of B, the compiler complains about access to F :-(
> Do I have to expose F as public to be able to access it when
> particular A is not a base for this particular B but when the A
> belongs somehow to this particular B which has some different A as
> base ?
>
> JAM

From: JAM on
On Jan 31, 10:36 pm, Peter Duniho <no.peted.s...(a)no.nwlink.spam.com>
wrote:
>
> That's correct.  To access a protected member of a base class, your
> class has to access that protected member via a variable of its own type.
>
> Consider the alternative: if you could start accessing protected members
> of _any_ instance of a class A just by inheriting A and doing it from
> the sub-class, then accessibility protection would be basically
> meaningless.  You could bypass it anytime you want just by inheriting
> the class you want to get at.

Sure, but I would do it on purpose so the assumption would be that I
know what I'm doing. I don't see the alternative as being so bad here.

> Note that if your "items" variable was a "List<B>", the access would
> have been just fine.  That's because the class B is trusted to access
> protected members in instances of itself.

But that actually would make my program less self explanatory. In my
program class A is a node in the tree structure.
Class B is a root node of that tree. B requires slightly different
handling than A, that is why it is derived from A.
The list is a list of subnodes. It would make akward reading if the
list would be a list of rootnodes. Function F in my program simply
opens particular branch (recursively) from data file. However root
node cannot use F to open itself. It uses different function. But then
it opens it's entire branch using F for all it's subnodes from the
list. There is no reason for F to be used anywhere else. That is why I
tought it would be a good idea to hide it from public interface.

>  From the C# 3.0 specification:
>
>      When a protected instance member is accessed outside
>      the program text of the class in which it is declared,
>      and when a protected internal instance member is
>      accessed outside the program text of the program in
>      which it is declared, the access must take place within
>      a class declaration that derives from the class in which
>      it is declared. Furthermore, the access is required to
>      take place through an instance of that derived class type
>      or a class type constructed from it. This restriction
>      prevents one derived class from accessing protected members
>      of other derived classes, even when the members are
>      inherited from the same base class.

Well. So it works as designed :-(

> > Do I have to expose F as public to be able to access it when
> > particular A is not a base for this particular B but when the A
> > belongs somehow to this particular B which has some different A as
> > base ?
>
> That sentence is pretty awkward.

Sorry. English is not my first language.

> I'm not sure it means what you meant
> it to mean.  But, if you're asking if you _have_ to use "public" to
> write code in one type B that can access non-public members in a base
> type A of that type B but without the compiler being able to verify that
> the instance is in fact an instance of type B, strictly speaking the
> answer is "no".  An alternative to "public" that doesn't have the same
> restriction as "protected" is "internal".  But that only works if the
> code is in the same assembly).

Internal is fine for my program.

> But as a general rule, yes…if you have a member in one class that you
> want to be accessible via code not in an instance of the class in which
> the member is defined, that member has to be public.

Well, then I think my particular case proves that C# in rare
situations is lacking more granular access control that would be
usefull.

> I would furthermore argue that if you find yourself trying to design a
> class to the contrary of this, that you've made a mistake in the program
> design.

What you think about my example ? In my experinece with tree
structures it often happens that root node has slightly different
needs that other nodes.

>  The accessibility rules are there for a reason, and even
> "internal" should IMHO be used VERY sparingly.  Any time you find
> yourself trying to get around the given accessibility rules, it suggests
> that you're leaking implementation details in a way that would negate
> the benefit of abstracting your types in the first place.

>
> Pete- Hide quoted text -
>
> - Show quoted text -

JAM