Coding guides: How do you split up your large source files?

10,703

Solution 1

I think your problem is summed up with the term you use: "Main C# file".

Unless you mean main (as in the method main()) there is no place for that concept.

If you have a catch-all utility class or other common methods you should break them into similar functional parts.

Typically my files are just one-to-one mappings of classes.

Sometimes classes that are very related are in the same file.

If your file is too large it is an indication your class is too big and too general.

I try to keep my methods to half a screen or less. (When it is code I write from scratch it is usually 12 lines or fewer, but lately I have been working in existing code from other developers and having to refactor 100 line functions...)

Sometimes it is a screen, but that is getting very large.

EDIT:

To address your size limit question about functions - for me it is less about size (though that is a good indicator of a problem) and more about doing only one thing and keeping each one SIMPLE.

Solution 2

In the classic book "Structured Programming" Dijkstra once wrote a section entitled: "On our inability to do much." His point was simple. Humans aren't very smart. We can't juggle more than a few concepts in our minds at one time.

It is very important to keep your classes and methods small. When a method gets above a dozen lines or so, it should be broken apart. When a class gets above a couple of hundred lines, it should be broken apart. This is the only way to keep code well organized and manageable. I've been programming for nearly 40 years, and with every year that has gone by, I realize just how important the word "small" is when writing software.

As to how you do this, this is a very large topic that has been written about many different times. It's all about dependency management, information hiding, and object-oriented design in general. Here is a reading list.

Solution 3

Split your types where it's natural to split them - but watch out for types that are doing too much. At about 500 lines (of Java or C#) I get concerned. At about 1000 lines I start looking hard at whether the type should be split up... but sometimes it just can't/shouldn't be.

As for methods: I don't like it when I can't see the whole method on the screen at a time. Obviously that depends on size of monitor etc, but it's a reasonable rule of thumb. I prefer them to be shorter though. Again, there are exceptions - some logic is really hard to disentangle, particularly if there are lots of local variables which don't naturally want to be encapsulated together.

Sometimes it makes sense for a single type to have a lot of methods - such as System.Linq.Enumerable but partial classes can help in such cases, if you can break the type up into logical groups (in the case of Enumerable, grouping by aggregation / set operations / filtering etc would seem natural). Such cases are rare in my experience though.

Solution 4

Martin Fowler's book Refactoring I think gives you a good starting point for this. It instructs on how to identify "code smells" and how to refactor your code to fix these "smells." The natural result (although it's not the primary goal) is that you end up with smaller more maintainable classes.

EDIT

In light of your edit, I have always insisted that good coding practice for back-end code is the same in the presentation tier. Some very useful patterns to consider for UI refactorings are Command, Strategy, Specification, and State.

In brief, your view should only have code in it to handle events and assign values. All logic should be separated into another class. Once you do this, you'll find that it becomes more obvious where you can refactor. Grids make this a little more difficult because they make it too easy to split your presentation state between the presentation logic and the view, but with some work, you can put in indirection to minimize the pain caused by this.

Solution 5

Don't code procedurally, and you won't end up with 4,200 lines in one file.

In C# it's a good idea to adhere to some SOLID object-oriented design principles. Every class should have one and only one reason to change. The main method should simply launch the starting point for the application (and configure your dependency injection container, if you're using something like StructureMap).

I generally don't have files with more than 200 lines of code, and I prefer them if they're under 100.

Share:
10,703
Nick Devereaux
Author by

Nick Devereaux

C# developer - .net 5, Asp.Net Webforms (yay), WCF, Winforms, SQL Server, Workflow, Typescript, Javascript.... Linux fan. Python inquisitor.

Updated on June 04, 2022

Comments

  • Nick Devereaux
    Nick Devereaux almost 2 years

    The project I'm working on has just hit 4200 lines in the main C# file, which is causing IntelliSense to take a few seconds (sometimes up to 6 or so) to respond, during which Visual Studio locks up. I'm wondering how everyone else splits their files and whether there's a consensus.

    I tried to look for some guides and found Google's C++ guide, but I couldn't see anything about semantics such as function sizes and file sizes; maybe it's there - I haven't looked at it for a while.

    So how do you split your files? Do you group your methods by the functions they serve? By types (event handlers, private/public)? And at what size limit do you split functions?

    To clarify, the application in question handles data - so its interface is a big-ass grid, and everything revolves around the grid. It has a few dialogs forms for management, but it's all about the data. The reason why it's so big is that there is a lot of error checking, event handling, and also the grid set up as master-detail with three more grids for each row (but these load on master row expanded). I hope this helps to clarify what I'm on about.