Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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?

share|improve this question

5 Answers 5

up vote 24 down vote accepted

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.

share|improve this answer
2  
+1 good point about the example being inner classes. –  mootinator Feb 28 '11 at 23:07
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. –  konrad Feb 28 '11 at 23:08
2  
I'd add that inner classes should be a rare exception and almost never should they be public. –  Josh Mar 1 '11 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 :) –  krystan honour Mar 1 '11 at 15:33

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, whats the filename AnimalPersonObject.cs thats just not feasible.

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 maintainance issues and you will find junior devs finding it hard to grasp the code.

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

share|improve this answer

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.

share|improve this answer
1  
Oh god - that sounds terrible. –  Sergio Feb 28 '11 at 23:09
    
Why are you asking? Did someone downvote you and you want to ask why? –  Sergio Feb 28 '11 at 23:12
    
Wait... were you referring to the small anecdote about my last job? If so, I mis-understood and apologize for such. –  Jesse C. Slicer Feb 28 '11 at 23:17
    
Agree completely. I'm working on a project where most files have at least 4 classes per file. And some have up to 22 classes + 1 interface per file. –  L_7337 2 days ago

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.

share|improve this answer
1  
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. –  James Beninger Aug 22 '12 at 18:03

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! :)

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.