views:

1911

answers:

18

Are there are good uses of Partial Classes outside the webforms/winforms generated code scenarios? Or is this feature basically to support that?

+3  A: 

LINQ to SQL makes good use of partial classes to extend designer generated code. I think you will typically find this pattern of partial classes being used by designer-created code.

Jason Jackson
+1  A: 

Where I'm at we have a program that handles incoming files from clients. It's set up so that each client's code is in it's own class library project, which knows how to handle whatever format that client chooses to use.

The main code uses the libraries by defining a fairly extensive interface that a class in the library must implement (probably should be a few distinct interfaces, but it's too late to change it now). Sometimes that involves a lot more code in the same class than we'd normally think prudent. Partial classes allow us to break them up somewhat.

Joel Coehoorn
+11  A: 

It is in part to support scenarios (WebForms, WinForms, LINQ-to-SQL, etc) mixing generated code with programmer code.

There are more reasons to use it. For example, if you have big classes in large, unwieldy files, but the classes have groups of logically related methods, partial classes may be an option to make your file sizes more manageable.

Justice
"if you have big classes in large, unwieldy files"Then you really need to reconsider your design.
Fredrik Kalseth
well this depends on your definition of large and unwieldy as well as on your tolerance for scrolling all over the place to see what your trying to see as well as your ability to use large/multiple screens / split panes to view your work. very subjective analysis; i have to disagree, Fredrik...
sweeney
@sweeney: If you decide that your classes are large and unwieldy enough to consider partials, then they're probably large and unwieldy enough to consider your design, no matter what your metric for "large and unwieldy" is.
Roger Lipscombe
@Roger: I disagree. If your class has nested types for completely valid encapsulation reasons, it will create large and unwieldy files that warrant the use of partials but don't indicate the need for a redesign.
Jeff Yates
+6  A: 

I use partial classes as a means of separating out the different sub elements of custom controls that I write. Also, when used with entity creation software, it allows products like LLBLGen to create generated versions of classes, as well as a custom, user edited version, that won't get replaced if the entities need to be regenerated.

MagicKat
+3  A: 

I find partial classes to be extremely helpful. Usually they are used to be able to extend autogenerated classes. I used them in one project with heavy unit tests. My UT classes had complex dependencies and it was not very practical to separate code across multiple classes.Of course it is better to use inheritance\composition but in some cases partial classes can be rally helpful.

aku
+1  A: 

On UserControls which are relatively complicated, I put the event handling stuff in one file and the painting and properties in another file. Partial classes work great for this, Usually these parts of the class are relatively independent and it's nice to be able to edit painting and event handling side by side.

Nick
A: 

Correction, as Matt pointed out, both sides of the partial need to be in the same assembly. my bad.

Ali Shafai
A: 

I use it in a data access layer. The generated classes like the mapper and queries a partial. If I need to add a mapper method for example to do a fancy load that's not generated I add it to the custom class.

At the end the programmer that uses the data layer in the business layer only sees one class with all the functionality he or she needs. And if the data source changes the generic parts can easily be generated without overwriting custom stuff.

Tobias
A: 

I just found a use for partial classes. I have a [DataContract] class that I use to pass data to the client. I wanted the client to be able to display the class in a specific way (text output). so I created a partial class and overrode the ToString method.

rob_g
+3  A: 

I often use partial classes to give each nested class its own file. There have been some architectures I've worked on where most of the implementation was only required by one class and so we nested those classes in that one class. It made sense to keep the files easier to maintain by using the partial class ability and splitting each one into its own file.

We've also used them for grouping stock overrides or the hiding of a stock set of properties. Things like that. It's a handy way of mixing in a stock change (just copy the file and change the partial class name to the target class - as long as the target class is made partial too, of course).

Jeff Yates
+5  A: 

Code generation was the driving force behind partial classes. The need comes from having a code-generated class that is constantly changing, but allow developers to supply custom code as part of the class that will not be overridden everytime changes are made that force the class to be regenerated.

Take WinForms or Typed-DataSets for example (or any designer for that matter). Everytime you make a change to the designer it serializes the corresponding code to a file. Let's say you need to provide a few additional methods that the generator doesn't know anything about. If you added it to the generated file your changes would be lost the next time it was generated.

A project that I'm currently working on uses code-generation for all the DAL, BLL, and business entities. However, the generator only get's us 75% of the information. The remaining portion has to be hand coded (custom business logic for instance). I can assume that every BLL class has a SelectAll method, so that's easy to generate. However My customer BLL also needs to have a SelectAllByLocation method. I can't put this in my generator because it's not generic to all BLL classes. Therefore I generate all of my classes as partial classes, and then in a separate file I define my custom methods. Now down the road when my structure changes, or I need to regenerate my BLL for some reason, my custom code won't get wiped out.

Micah
A: 

Sometimes you might find terribly old code at work that may make it close to impossible to refactor out into distinct elements without breaking existing code.

When you aren't given the option or the time to create a more genuine architecture, partial classes make it incredibly easy to separate logic where its needed. This allows existing code to continue using the same architecture while you gain a step closer to a more concrete architecture.

nyxtom
A: 

I worked on a project a couple years ago where we had a typed DataSet class that had a ton of code in it: Methods in the DataTables, methods in the TableAdapters, declarations of TableAdapter instances, you name it. It was a massive central point of the project that everyone had to work on often, and there was a lot of source-control contention over the partial class code file.

So I split the code file into fix or six partial class files, grouped by function, so that we could work on smaller pieces and not have to lock the whole file every time we had to change some little thing.

(Of course, we could also have solved the problem by not using an exclusively-locking source-control system, but that's another issue.)

Kyralessa
A: 

Anywhere you'd have used #region sections before probably makes more sense as separate files in partial classes.

I personally use partial classes for large classes where static members go in one file and instance members go in the other one.

Mark Cidade
+1  A: 

Generally, I consider it a code smell.

If your class is that complicated then it can probably be broken up into smaller reusable components.

Or it means that theres no inheritance hierarchy where there should be one.

For code generation scenarios it's good but I think code generation is another code smell.

flukus
Out of curiosity, what do you define as code smell?
Luis Filipe
Over use of code smell is a code smell.
Hogan
A: 

EDIT: DSL Tools for Visual Studio uses partial classes.

Thus, it's a feature that many automatic generated code uses. Instead of using #region the automatic generated code goes to one file and the user code (also called custom code) goes to another and even in different directories so that the developer does not get confused with so many meaningless files.

It's good to have this choice which you can combine - but not forced to use -with inheritance

Also, it can be handy to separate the logic of some classes among several directories. Of course, for machines, it's the same, but it enhances the user readability experience.

Luis Filipe
+1  A: 

As mentioned earlier, I too think this is a code smell.

If a class is so big that it needs to be split into more files, means that it is breaking the single responsibility principle and doing too many things. The large class could be broken down into smaller classes that cooperate together.

If you have to use partial classes or regions to organize code, consider if they should be in their own classes. It increases readability and you'd get more code reuse.

Hibri
+2  A: 

Another possible use for partial classes would be to take advantage of partial methods to make methods selectively disappear using conditional compilation - this would be great for debug-mode diagnostic code or specialized unit testing scenarios.

You can declare a partial method kind of like an abstract method, then in the other partial class, when you type the keyword "partial" you can take advantage of the Intellisense to create the implementation of that method.

If you surround one part with conditional build statements, then you can easily cut off the debug-only or testing code. In the example below, in DEBUG mode, the LogSomethingDebugOnly method is called, but in the release build, it's like the method doesn't exist at all - a good way to keep diagnostic code away from the production code without a bunch of branching or multiple conditional compilation blocks.

// Main Part
public partial class Class1
{
    private partial void LogSomethingDebugOnly();

    public void SomeMethod()
    {
        LogSomethingDebugOnly();
        // do the real work
    }
}

// Debug Part - probably in a different file
public partial class Class1
{

    #if DEBUG

    private partial void LogSomethingDebugOnly()
    {
        // Do the logging or diagnostic work
    }

    #endif
}
David