42

I have been using the partial class modifier for some time in order to put helper classes in their own file.

Today we got a new guy and he said that the last team he worked with didn't allow partial classes for this because modifying a helper class that is in a separate file would cause the main partial class file to get out of whack with the changes. Also, they were only allowed to put a helper classes inside of the main class as the last resort so that everything remained decoupled.

What do you think? Is there any problem using partial classes like this or does it boil down to preference?

For instance, I usually have something like this:

  • MainClass.cs
  • MainClass.Helper1.cs
  • MainClass.Helper2.cs

...

// Inside of MainClass.cs I have code like this:

public abstract partial class MainClass
{
    // ...
}

// Then in the MainClass.Helper1.cs I have:

partial class MainClass
{
   private class Helper1
   {
       // ...
   }
}
Wayne Bloss
  • 5,370
  • 7
  • 50
  • 81

10 Answers10

32

Partial classes are primarily for code-generator usage, such as designers - but I use the approach you have cited - in particular when an object implements multiple (non-trivial) interfaces, I find it useful to break it up 1 file per interface implementation. I also commonly have a file for the static methods, which are usually different enough from instance methods to warrant separation.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
8

Personally I can't see anything wrong with using partial classes like this, but that's just my own opinion. The only thing that might seem like "bad practice" is to name your classes "Helper1" and "Helper2" (but that might be an example only for clarification).

If you're using partial classes like this, check out the (free) addin vsCommands (for Visual Studio 2008) that makes it really easy to group files in the solution explorer (just like designer files) without editing the project file.

Patrik Svensson
  • 13,536
  • 8
  • 56
  • 77
5

Short answer: If all of the classes are your code, you don't really need helper classes, which invalidates your need for partials.

Long answer: I'm not sure that there is anything that says your practice is explicitly wrong. From my experience, if you've got several different files that compose the entire class, you do need a good reason to do so, because:

  1. Partial classes reduce readability somewhat
  2. If your classes have multiple helper classes within them, it may be a symptom of a poor design, I don't think I've ever run into a situation where I was forced to write helper classes for classes I created.

However, I think the best reason to use partial classes is code generation, where you want to be able to re-generate a file without losing custom work.

Zachary Yates
  • 12,966
  • 7
  • 55
  • 87
  • 1
    You never need helper classes, really? It surprises me because I see so many classes in the framework itself that have helper classes like private enumerators and private lists (Dictionary..KeyCollection, Dictionary..ValueCollection etc...). – Wayne Bloss Dec 09 '08 at 00:19
  • For instance... System.Enumerable has about 30 helper classes nested inside of it. (THIRTY!!) So I guess that you'd say this is possibly a bad design? – Wayne Bloss Dec 09 '08 at 00:41
  • "re-generate a file without losing custom work" is definitely the best reason for a partial class, so convenient, so useful – ChrisHDog Dec 09 '08 at 00:42
  • Well, I don't mean that helper classes are bad design. I don't use helper classes if I own the main class. I build the "helper" functionality into the main class. I do use helper classes when I don't own the main class (such as a framework/3rd party class). – Zachary Yates Dec 09 '08 at 03:34
2

In my experience, there no difference between noramal class and partial class.If your design requires large stucture of class or implementing more interfaces then go for partial class. Any how both are same.

Pitambar
  • 51
  • 4
2

I'm not a very big fan of partial classes and don't use them myself.

The one time I do find them helpful and OK to use however is when you want to add something to the LINQ to SQL designer code, but apart from that I find if you are spreading the code out into different files just for the sake of it, it can make it very hard to read and manage.

Maybe if you have classes split into many files maybe your classes are doing to much... just a thought:)

Nathan W
  • 54,475
  • 27
  • 99
  • 146
  • I actually find it easier to manage if each class has it's own file... That way I can have the nested class open in one window and the parent class in another window and flip back and forth more easily. – Wayne Bloss Dec 09 '08 at 00:29
  • Also, see my comment on Andrew's answer below "I guess that I don't see what size has to do with the class being nested or not..." – Wayne Bloss Dec 09 '08 at 00:30
2

I've actually done the same thing. As has been stated, there is a slight readability hit on deciphering the partial classes.

Decoupling is the main reason I like this solution. A private inner class is far less coupled to everything else, because nothing else can see it or use it (although they may be talking about the potential for it to access the parent class's private data, which would usually be a bad idea).

Neil
  • 7,227
  • 5
  • 42
  • 43
1

I usually never use partial classes for similar reasons stated above.

But! While not frequent I have sometimes found that extensively unit testing a class (usually external classes) leads to giant unit test classes. Splitting the unit test class into partial classes makes it a bit easier on the eyes and to understand.

Similar to the grouping idea when inheriting from multiple interfaces, unit test can be grouped for functions.

Choco Smith
  • 1,658
  • 18
  • 24
1

I think that if the nested classes are large enough that you feel the need to split them into their own files they should probably not be nested classes. Make them internal members of the same namespace as MainClass instead.

Partial classes really only exist to support code generators and using them to break programmer written code into manageable chunks is an indicator of poor design.

See this article for a hilarious example of what not to do with partial classes.

Andrew Kennan
  • 13,947
  • 3
  • 24
  • 33
  • I guess that I don't see what size has to do with the class being nested or not. A nested class is not usable by other classes so I nest a class purely to achieve that functionality. Then I put it into it's own file regardless of it's size so I can edit the nested class separately. – Wayne Bloss Dec 09 '08 at 00:27
  • Excellent link. And it might even be cogent. – dkretz Dec 09 '08 at 00:38
  • I usually use inner classes for simple data storage. I'm not a fan of partial classes for anything other than code generators because they reduce readability of the code - especially if someone lazily puts a MainClass method in the MainClass.Helper1.cs file. – Andrew Kennan Dec 09 '08 at 00:47
0

I think it's good to remember that your tool's default behavior is to create a low-level form of Coupling Not Cohesion; and view it skeptically, and override it unless it makes sense for some of the specific reasons listed above. But it's not good default behavior.

dkretz
  • 37,399
  • 13
  • 80
  • 138
0

Most of times I use partial class only with code generation, so I can extend my classes' behaviors on separated classes that they need some customization and don't include in code generation.

Samnang
  • 5,536
  • 6
  • 35
  • 47