How do you organize C# code in to files?

In C#, the questions of what types to create, what members they should have, and what namespaces should hold them, are questions of OO design. They are not the questions I'm interested in here.

Instead, I want to ask how you store these in disk artifacts. Here are some example rules:

  • Put all of an assembly's types in a single source file. One friend who did this said "files are an archiac code organization tool; today I use classview and Collapse to Definitions to browse my code".

  • Put all your code in one assembly. Makes deployment & versioning simpler.

  • Directory structure reflects namespace structure.

  • Each namespace gets its own assembly.

  • Each type goes in its own assembly. (Listed as an extreme example.)

  • Each type gets its own source file.

  • Each member gets its own file; each type gets its own directory. (Listed as an extreme example.)

Answers


Whatever you do, just PLEASE do it consistently. I don't believe there is any one single answer (though there are a few wrong ones). But just make sure you stay true to your form as this will be the key for your successor(s) to find things easily.


Currently I do:

  • One assembly for production code + unit tests
  • directory structure mimics namespaces
  • one type per file
    • nested types get their own file, using partial types. That is:


// ------ C.cs

public partial class C : IFoo
{
    // ...
}

// ------ C.Nested.cs
partial class C
{
    public class Nested
    {
        // ...
    }
}

I do it quite similarly. One point where I differ:

  • one type per file

I declare delegate types where I need them, i.e. not in their own file but rather in the class that uses them.


I create one assembly per architectural layer. (WinUI.exe, BusinessWorkflow.dll, BusinessComponent.dll etc.

Then, one physical file per class.

So that's "vertical".

Namespaces, conceptually, go horizontally, grouping domain level functionality together. All the customer stuff goes in a "Customer" namespace, say, Orders go in "Accounting.AccountsPayable" for example.

As each assembly only reference the one beneath it in - architecturally, your intellisense is constrained nicely by relevant references within your domain model.

(Have to agree with above though - consistency is vital.


For tiny projects with less than a dozen classes, just one class per file.

For enterprise projects, I have multiple projects in a solution. They are grouped by purpose (business classes, interfaces, UI). Each class has its own file.


No matter how small a type is, put each type into a separate file - Exception: nested classes and delegates

By the way, using a partial class to separate for the sole purpose of placing a nested type in its own file seems like an overkill. Partial classes should be used judiciously and typically to be used for file generation tools - You have to consider how to "name" your partial classes for nested classes. Coming up with an intuitive name for physical nested file can be tidious and it is definately not a simple task.

For projects, name your projects to reflect namespaces - Exception: When a nested namespace gets big, I would migrate a nested folder into another project.


I prefer the conventional one-file-per-public-class, with folders inside the project (which map to sub-directories) used to group conceptually related classes as needed to keep the Solution Explorer view manageable. If your class names are well chosen the folders shouldn't be strictly necessary, but they are helpful if the project has a lot of classes.

Using separate files for nested types seems like overkill, at least if the nested classes are relatively simple 'helper' classes, and particularly so if they are private.

The main practical objection to your friend's "everything in one huge file" scheme is that Visual Studio tends to get very, very slow when it tries to deal with very long code files.


I prefer this kind of organization in whatever language.

Related small classes in their own file(s).

Big classes in their own file.

Directories for separate subprojects.


Need Your Help

Sensitive data in Viewstate?

c# asp.net viewstate

I need to store sensitive data across few pages (run over https) per session.

LDAP Query C# With Windows Server Essentials Role Office 365 mailnickname

c# email ldap

I have a legacy application that used LDAP query to get back the mail address and use Web Services of Exchange to send the message. I have added support for Office 365 and was able to use our corp...