Hazem Elshabini

Hello,

i'm working on a project, i've faces a simple problem, i just wanna make sure i have the optimum solution.

i need to access encolsing class member from a nested class.

i tried different approaches, alot of them work...i need to know which is better.

Method 1: Using Inheritance:

Code Snippet

public class A

{

//this is the member.

private int member1;

//a property (polymorphism).

public int member1Property

{

get

{

return member1;

}

}

//this is the nested class

//note that i used inheritance.

//also not that inheriting from an enclosing class caused me to reach both private and public members, which i dont like.

public class B : A

{

int member1B = member1;

int member1BfromProperty = member1Property;

}

}

Method 2: Using static members:

Code Snippet

public class A

{

//this is the static member.

private static int member1;

//a property (polymorphism).

public int member1Property

{

get

{

return member1;

}

}

//this is the nested class

//note that i didn't use inheritance.

//also not that i refered to the static member directly from the nested class.

//however sometimes using static variables causes some problems (ain't i right )

public class B

{

int member1B = member1;

int member1BfromProperty = member1Property; //inaccsesible, generates error

}

}

well is there any better way than those 2 way...i dont seem to like them, as i fear using static members, and this kind of inheritance is stupid since it reaches members with any kind of access modifiers.

thank you in advance,




Re: Visual C# Language Accessing enclosing class members from a nested class.

TaylorMichaelL

Firstly nested types are not normally recommended. Use them only as an implementation detail and, even then, an internal class is better. A common example of a nested type is a custom enumerator for a collection. The enumerator often needs implementation information about the parent type and it is useless outside the parent. A nested type is appropriate.

Under no circumstances should you ever use anything other than a private nested type. A public/protected nested type should be expose as a regular type. An internal nested type is private outside the assembly but public inside so it should follow public nested type rules. In the enumerator example the enumerator is private and sealed. The enumerator is exposed by the parent class through GetEnumerator which returns an interface.

Still if you want to use a nested class then go ahead. Given that a nested type should always be private the accessibility of the members are irrelevant since the nested type is strictly there as a support for the parent type. Making all the members public and skipping properties is perfectly reasonable. If you start designing a nested type with properties and validation and whatnot then you need to ask yourself if it might be better for the type to not be nested.

Nested types have one interesting property over non-nested types. They can access the private and protected members of the parent type (assuming the instance of the parent type is someone conveyed to the nested type instance. This falls back to the fact that a nested type should only be used to help implement a class. Therefore you should make any members of the nested type public so your parent type can do what it needs to do. However be sure to keep the nested type as private so others can't use it.

Do not use inheritance to the base class. Instead pass the instance of the owning type to the constructor of the nested type. You then have access to all the members of the parent type. You probably assumed that if you inherited the nested type from the base type that you would have access to the parent type's member, and you would have. But the instance you referenced would not be the instance that actually owned the nested type instance. It would have been a new instance. Use the constructor approach instead.

Code Snippet

public class ParentType
{
private string SomeField;

private NestedType m_Impl;

public ParentType ( )
{

m_Impl = new NestedType(this);

}

private class NestedType

{

private ParentType m_Parent;

public NestedType ( ParentType parent )
{ m_Parent = parent; }


public void Foo ( )
{

m_Parent.SomeField;

}

}
}

Michael Taylor - 9/25/07

http://p3net.mvps.org





Re: Visual C# Language Accessing enclosing class members from a nested class.

Peter Ritchie

"Under no circumstances should you ever use anything other than a private nested type" is a bit harsh. Protected nested types are useful if you want a type only accessible to the containing type and all it's derived types. Something you can't do with an internal non-nested type.






Re: Visual C# Language Accessing enclosing class members from a nested class.

TaylorMichaelL

Yes it is harsh but I haven't run across a situation where a protected nested type is useful. Nested types are implementation details so they are irrelevant to everybody else (including derived types). Derived types should access the nested type through either a non-nested base type class or an interface exposed as a protected property. Otherwise you can't change the implementation without potentially breaking a derived type. IMHO.

Michael Taylor - 9/25/07

http://p3net.mvps.org





Re: Visual C# Language Accessing enclosing class members from a nested class.

Peter Ritchie

Yes, protected nested type should be rare, and so should private nested types. Take the nested enumerator type for example, if you want to create a base class so other derivatives can specialize the collection, you'll likely need to provide some sort of access to that enumerator nested type--something you can't do without making it protected or extracting it out of the class and making it its own class (which would mean elevating private data in the original class to everything within the assembly, as internal). I'm not a big fan of providing access to implementation details like that, even if it's just internal; so I prefer using protected nested types in these rare circumstances because the existence of that type is an implementation detail of the base class.

Creating a new non-nested interface simply to facilitate derivatives communicating back to the base through a protected property needlessly pollutes the namespace and is a good example of something that could be implemented as a protected type. That public interface can now be coupled to any other type; making that interface protected nested would avoid that.






Re: Visual C# Language Accessing enclosing class members from a nested class.

TaylorMichaelL

Let me clarify. I didn't mean create a new interface just to expose a nested type. That wouldn't make any sense. I meant expose the nested type through one of its interfaces. The enumerator is a good example. If I wanted derived classes to have access to the nested type I would expose it as IEnumerator<T> or similar. The only time this wouldn't work is if a derived type really, really needed to have access to the raw enumerator but, again, I've never seen this occur in practice. Otherwise I believe we are in agreement.

Michael Taylor - 9/25/07

http://p3net.mvps.org





Re: Visual C# Language Accessing enclosing class members from a nested class.

Peter Ritchie

I must be getting confused because you'd already have exposed the IEnumerator<T> (or IEnumerator) interface if it's an enumerable type. Exposing something that only derivatives can access implies they need something more than IEnumerator<T> provides...




Re: Visual C# Language Accessing enclosing class members from a nested class.

TaylorMichaelL

Yes in the case of the enumerator example you would probably just use the public GetEnumerator method however that is just an example. Let's switch to a different example. Maybe you have a class that exposes a read-only collection of objects. Internally it maintains the collection using a custom nested type. It would expose this collection to derived types through a standard ICollection interface so they could change the collection while publicly it was read only. Just an example, of course. My point was that even derived types should be as loosely coupled to the base type's implementation as possible. To achieve this you should prefer exposing an interface or non-nested type in lieu of the nested type itself. This gives you more flexibility. Of course there are times when a derived type has to be strongly coupled to a base class but these situations should be avoided whenever possible.

Michael Taylor - 9/25/07

http://p3net.mvps.org





Re: Visual C# Language Accessing enclosing class members from a nested class.

Peter Ritchie

Yes, you should prefer to use existing public interfaces. But when you don't have an existing interface to expose, or the interface only pertains to that type and it's derivatives; creating a new public interface is needlessly exposing implementation details.

In the case of enumerable types. If you want to expose detail to derived types, with regard to enumeration, that IEnumerator can't provide and you've already implemented a nested type, simply making that nested type protected will provide derivatives the ability to get at that information. You could add protected properties/methods on the base class itself; but if they pertain only to enumeration, providing that method/property on the nested type is much more appropriate.

But yes, that's extremely rare and I wouldn't go out of my way (or suggest it) to implement something like that unless I had to.






Re: Visual C# Language Accessing enclosing class members from a nested class.

Hazem Elshabini

well,

i have more than 20 classes in my library.

alot of them are nested and public.

i have had no problem so far, but i need it to be nested, otherwise all classes would be swarming in the namespace ^o)

im really confused how should i re-arrange what is currently arranged and works






Re: Visual C# Language Accessing enclosing class members from a nested class.

Peter Ritchie

Avoiding namespace pollution is not a good reason to make a class nested. If it's an implementation detail of a class (and is only used by that class) is should be private nested in that class.

If the nested class is used by other classes (i.e. you can't make it public or protected) then it shouldn't be nested.






Re: Visual C# Language Accessing enclosing class members from a nested class.

Hazem Elshabini

thats alot for the help guys,

but while we're on the subject what are more suitable ways to avoid namespace pollution

without ofcoarse creating nested classes






Re: Visual C# Language Accessing enclosing class members from a nested class.

Peter Ritchie

Moving towards C# 3.0 there's ways of reducing pollution with things like anonymous

types. If you need to have a class, there's not much you can do until 3.0. But, if you want to reduce the amount of methods, there's an article about that on the C# Developer Center: http://msdn2.microsoft.com/en-ca/vcsharp/bb308725.aspx






Re: Visual C# Language Accessing enclosing class members from a nested class.

sirjis

You could also try making more of a namespace hierarchy to organize your classes. For example, I've used sub-namespaces like Forms, Controls, Comms, Messages -- whatever is appropriate for your application.