I am having a bit of a debate about the use of nested classes. The situation is that a class name makes sense to be repeated in two or more places, and while there is moderate similarity between each of the different instances, they are generally different. The nested classes are not often (if at all) needed beyond the scope of their parent class.
So then, rather than just coming up with three different class names, this seems to make more sense to me.
class A {
class B {
}
class M {
class B {
}
}
class Q {
class B {
}
}
The obvious problem with that is not functionality, but rather consistency/repetition. I was wondering if other developers have ever struggled with the same thing, and what some of the opinions were.
It looks okay when your classes are small. Once they get bloated, you really start thinking about moving them in separate files.
More to your point, if you want to use both A.B and M.B in the same code you have to always type A.B and M.B, which can be a pain.
There's nothing inherently wrong about nested classes, as long as you stick to the following rules of thumb:
Never public or internal. There are special cases, such as when you're using a nested class to implement IEnumerator. But even then, the class itself should be kept private, since instances of it are being returned as IEnumerator, and it's really just being done as a way to avoid junking up the namespace with classes that aren't supposed to be instantiated.
Keep them small. A private nested class that's really just used for storing and passing around data in a more organized way is fine, and can sometimes be a very useful tool. (Not entirely unlike how anonymous classes are useful.) But if you're looking to use them to package up large chunks of functionality, it becomes a code smell that suggests you might want to consider refactoring the outer class instead.
Well you can use namespaces to do things like this too (just create a new folder in VS). Which is better for organising and will pretty much give you the same result.
But if the subclass is only relevant to the parent class then I don't see the harm in it.
Then again, if you are calling them the same thing I would guess they do a similar drop and you may want to look into abstraction, perhaps your parent classes could be done differently too. Really depends on what you need them to do though
If class
B
has any similarities between each inner class instance, would it make sense for you to abstract the similarities ofB
to a base class that exists alongsideA
,M
, andQ
? (I think so.) Then your inner classes, while they may have the same name, would be a little cleaner.With that said, this type of structure can be seen for things like Metadata in an MVC application. In that instance you'd have something like:
In these case the inner classes each serve the same purpose but their implementations vary with each parent class. Also, with the
Metadata
definitions here, it makes a lot of sense to keep a class that helps describe its parent as an inner class. If there's any chance you might want to re-use the inner classes elsewhere then I would move them outside of their parents.I think it's a little atypical to see this in practice otherwise. I'm sure there are good examples, but I bet there are more bad examples of this type of pattern.
I understand your sample is sort of contrived. Still, if your class names are similar enough - or identical - you really shouldn't make them nested classes. As a general rule you should shy away from using nested classes at all.
If I'm remembering correctly, the .NET Framework Guidelines recommends against using nested classes as well. Nested Type Usage Guidelines is a little old (back to version 1.1), but the principles still apply.
I like doing that, for me it makes the use more clearer and especially finding names less of a problem. But usally i try to limit this on private classes or public enums. For example
or