32

Is it advisable to create multiple classes within a .cs file or should each .cs file have an individual class?

For example:

public class Items
{
    public class Animal
    {
    }

    public class Person
    {
    }

    public class Object
    {
    }
}

Dodging the fact for a minute that this is a poor example of good architecture, is having more than a single class in a .cs file a code smell?

6 Answers 6

34

The example you gave is actually fine in my opinion. You are declaring inner classes, so it is perfectly sensible to keep them in the same file. The only way around this would be to make your Items class a partial class and split it over multiple files. I'd consider this bad practice. My general policy for nested classes is that they should be small and private. There are two exceptions to this:

  • you are designing a class cluster (more common in objective-c), thus it may be sensible to use the partial class approach
  • you need an enum that is only used with the public API of the parent class. In this case I prefer having an public enum declared inside the parent class instead of polluting my namespace. The enum being an "inner enum" effectively results in giving it a well defined scope.

If you word the question a little differently and ask about "Should I put each namespace-level class into its own file" then my answer would be "yes".

When designing classes we respect the Single Responsibility Principle. Reading code becomes a lot easier if its shape follows its semantics, hence splitting files by class is sensible.

From a mechanical point of view, having a file per class has several advantages. You can open multiple classes at the same time in different windows. This is especially important since no serious developer works with less than two screens. Being able to have more context in front of my head means I can keep more context in my head. (Most IDE's will allow you to open the same file twice, but I find this awkward).

The next important aspect is source control and merging. By keeping your classes separate, you avoid a lot of hassle when changes to the same file are made because separate classes need to be changed.

3
  • 1
    I agree, but then again inner classes is very uncommon in my experience. To be fair there isn't really that much that can really justify inner classes, the only case I know of is IEnumerable classes where you don't really are about the actual class as long as you can enumerate it. In all other cases each class should get it's own file. If for no other reason because of source control issues.
    – Homde
    Commented Feb 28, 2011 at 23:08
  • 2
    I'd add that inner classes should be a rare exception and almost never should they be public.
    – Josh
    Commented Mar 1, 2011 at 6:00
  • Yup teaches me for being so quick off the mark, inner classes are fine, however asking if you should use innerclasses is another question :) Commented Mar 1, 2011 at 15:33
11

To be brutally honest, please don't add more than one root class to a file. At my last job, there were files with not only multiple classes, but multiple namespaces and this stretched into the multiple thousands of lines of code. Very difficult to try to follow.

If there are classes that are closely related, then either name their files similarly or put them in a subfolder.

Physical separation of class files helps (note, not the end all-be all) engender separation of concerns and a more loose coupling.

On the other hand, your example is not showing more than one root class. There are several nested classes (note: try not to make nested classes anything but private if you can design this) and this is perfectly fine to have in one file.

0
8

If the files are highly cohesive, for instance where it is an alternative to having several very short, similarly named files, then it can be a good idea.

For instance, I find that when using Fluent NHibernate it's easier if I keep Entity and EntityMap in a single file, despite what my tools may have to say about that.

In most cases, it just makes classes harder to find. Use sparingly and with caution.

1
  • 2
    Specifically for Fluent NHibernate, I found it useful to keep them not only in the same file, but the same class as well. All of my entities have a nested class called Map. Commented Aug 22, 2012 at 18:03
8

Simply put yes, its not good form to do this and I'll tell you why. A bit later when your solution becomes big you will forget where the classes are as the file name will no longer represent what the contents are, What's your filename? Is it AnimalPersonObject.cs, that's not clear its multiple classes rather a single class called AnimalPersonObject

Sure you can get around this by using features in tools like Resharper to jump to types, but 1 class per file (including interfaces) is really the backbone of any code standard I've ever seen, not just in .Net but in Java and C++ and lots of other languages, those that don't often have maintenance issues. As currently written you will find junior developers finding it hard to grasp the code.

Almost all code optimisation tools will tell you to move the classes into a separate file, so for me yes this is a code smell and needs something to neutralise it :)

4

Another issue is that with very large and similar classes in the same file - when you can't see the class declaration at all times - you may end up putting breakpoints in the wrong class and wondering why they don't get hit... grrr! :)

-3

Basically, if you only need to use this class from within the "parent" class (in terms of scope), then it is usually appropiate to define it as a nested class.