74

I'm wondering why the 'partial class' concept even exists in C#/VB.NET. I'm working on an application and we are reading a (actually very good) book relavant to the development platform we are implementing at work. In the book, the author provides a large code base/wrapper around the platform API and explains how he developed it as he teaches different topics about the platform development.

Anyway, long story short - he uses partial classes, all over the place, as a way to fake multiple inheritance in C# (IMO). Why he didn't just split the classes up into multiple ones and use composition is beyond me. He will have 3 'partial class' files to make up his base class, each w/ 3-500 lines of code... And does this several times in his API.

Do you find this justifiable? If it were me, I'd have followed the S.R.P. and created multiple classes to handle different required behaviors, then created a base class that has instances of these classes as members (e.g. composition). Why did MS even put partial class into the framework? They removed the ability to expand/collapse all code at each scope level in C# (this was allowed in C++) because it was obviously just allowing bad habits - partial class is, IMO, the same thing. I guess my question is: Can you explain to me when there would be a legitimate reason ever to use a partial class?

EDIT: I'm aware that for Web/WinForms there is no other choice. But outside of this? Why didn't MS just put some different keyword for gluing code-genn'ed classes together? Or is there really a legit design scenario that merits it?

I do not mean this to be a rant / war thread. I'm honestly looking to learn something here. When should partial classes be used in code design? Simple question, no need to close

Thanks

76484
  • 8,498
  • 3
  • 19
  • 30
dferraro
  • 6,357
  • 11
  • 46
  • 69
  • Duplicate: http://stackoverflow.com/questions/160514/partial-classes-in-c – Jeff Yates Mar 19 '10 at 14:14
  • Re: Your edit - generated code is still code. How is the compiler to differentiate between a generated `partial` keyword and one that the programmer wrote? – Aaronaught Mar 19 '10 at 14:19
  • I voted to close because this is a duplicate. – Jeff Yates Mar 19 '10 at 14:21
  • Where is Jon Skeet when you need him? – Onion-Knight Mar 19 '10 at 14:22
  • 2
    Jeff, thats a year old thread (remember we have a new version of .NET/VS out now) that I didnt find when searching.... I also in my thread explained my unique situation of the code that I am looking at and asked if it was an abuse of 'partial' - where in the thread you linked to does it talk of these topics? Not a dupe when I'm talking about a specific scenario I've run into.. – dferraro Mar 19 '10 at 14:24
  • 7
    Partial classes don't exist in .Net. They do in C#. It is a compile time thing. – Dykam Mar 19 '10 at 14:36
  • @ Aaronaught - good question, that's for the MS .NET development team to figure out =) – dferraro Mar 19 '10 at 14:45
  • @dferraro: Your question is "Can you explain to me when there would be a legitimate reason to ever use a partial class?". I can see it. Just up there. THe other question asks the same thing. Therefore, duplicate. We can split hairs all day but the question is the same and gives the same answers. – Jeff Yates Mar 19 '10 at 14:45
  • @Dykam, semantics, we all know what I mean (.NET languages). But I've edited it for you anyway =) – dferraro Mar 19 '10 at 14:46
  • I know, but people without proper .Net knowledge will easily read this as a .Net fail. Took me a while too before I understood that partial classes where C# side. – Dykam Mar 19 '10 at 15:15
  • +1 This may be a partial dup, but if it hadn't been posted, I probably wouldn't have stumbled on it, or the other question. Both questions have valuable answers. – Tom Bushell Mar 19 '10 at 15:26
  • thanks everyone for the replies, definitely learned a lot from this. What I haven't figured out though is how the hell my rep went from 900 n change to under 500 from posting this thread... WTF? – dferraro Mar 22 '10 at 15:23
  • @dferraro This seems to be a consequence of a global rep recalc of March 2010 http://meta.stackexchange.com/questions/42904/the-global-reputation-recalc-of-march-2010 – Daniel Daranas Mar 29 '10 at 16:38
  • 1
    Coming from C++ and Java, I think they are largely unnecessary. I know a lot of people have said they're useful for separating auto-generated code and custom extensions but there are simple alternative solutions to this problem which have a much smaller potential of being abused. – W.K.S Jul 12 '12 at 18:55
  • I'm curious why you think he's using partials to fake multiple inheritance; you get a compile-time error if you try to specify a different base class across different partial definitions. Or, is he instead implementing different Interfaces in each partial definition? (ie Aaronaught's answer below: http://stackoverflow.com/a/2477910/237723) – JoeBrockhaus Nov 29 '14 at 17:56
  • Main question is.. Which book it was? – Teoman shipahi Aug 03 '15 at 21:47

15 Answers15

107

Can you explain to me when there would be a legitimate reason to ever use a partial class?

One of the most legitimate and useful reasons is to encourage the separation of automatically generated code and your own custom extensions to it. For instance, it's common to have an automatically generated form code from some kind of designer, but you usually want to add your own specific behavior to it. This way, if you regenerate the automatic-code portion, you're not touching the part that has your specific extensions.

That said, it's quite possible to have too much of a good thing. Some tips:

  • Don't make your classes partial for the sake of being partial.

  • Don't put partial classes anywhere except besides one another. If you have to jump to a completely unrelated section of the project to see the other half of the class, you're probably doing it wrong.

  • Don't use partial as a technique to obscure the size of the class. If you're breaking up your classes with partial because they're too big, you should revisit the Single Responsibility Principle.

  • If you have three or more partial fragments for the same class, it's almost a guarantee that you're abusing partial. Two is the typical upper bound of reasonableness, and it's generally used to segment automatically-generated code from handwritten code.

Anyway, long story short - he uses partial classes, all over the place, as a way to fake multiple inheritance in C# (IMO). Why he didnt just split the classes up into multiple ones and use composition is beyond me. He will have 3 'partial class' files to make up his base class, each w/ 3-500 lines of code... And does this several times in his API.

Yes, that's definitely a clear abuse of partial!

John Feminella
  • 303,634
  • 46
  • 339
  • 357
  • OK, you got me there, and you're right about designer generated code in Win and Web forms... But, IMO that's abolustely the only time I could ever see it being used. If you're following the SRP, you shouldnt need to ever type the partial keyword in your own classes... If this is the case, why doesnt MS put some different keyword that only allows these 'glueing' of classes to happen for code-generated tools, and send 'partial' to the same abyss where they put collapsing-an-if-statement? – dferraro Mar 19 '10 at 14:10
  • 7
    @dferraro: I disagree. Sometimes it is entirely valid to have a nested type within a class and it is good practise to give that nested type its own file. – Jeff Yates Mar 19 '10 at 14:16
  • 12
    @dferraro » Code is code is code. A compiler can't tell the difference between generated code and code that was typed by a human without some special designation -- which is more work, not less. Besides, as a general rule, it's better when languages allow you more flexibility and don't impose a particular mindset of the best way to do something. Part of good design is knowing that you can't possibly anticipate every situation in advance, and knowing when to break the rules. – John Feminella Mar 19 '10 at 14:31
  • I see what you mean on the first... but I disagree with your last statement... I think development platforms should be more like government (and government more like development platforms)... There should be restrictions (within reason) on what you can/can't do. This is why they removed multiple inheritence in .NET. And also removed the collapsing of all scope braces in VS... etc... but I suppose that's a topic for another thread =) – dferraro Mar 19 '10 at 15:03
  • 11
    @defarraro: Multiple inheritance wasn't removed from .NET - it was never added. – Jeff Yates Mar 19 '10 at 16:42
  • 4
    "Collapsing of scope braces" is an IDE feature, not a language one. Also, multiple inheritance wasn't included because of the fact that the tradeoff of functionality vs. complexity was too great, not because not having multiple inheritance is necessarily a good restriction. Finally, on a somewhat more personal note, I think there are lots of things that could stand to be _less_ like government, contrary to your assertion. – John Feminella Mar 19 '10 at 18:51
  • @Jeff, since you love so much about arguing over semantics, my username is *'dferraro'*.... Yes, Duh, C# never had multi-inheritence. But we all know what I meant - that *C#/Java the children of C++ did not include multi-inheritence because it encourged poor architecture design*... Ditto on the Scope Braces comment - like I really believed a compiler understood what collpasing code meant. Obviously I was talking about *Microsoft* removing that feature from *Visual Studio*... I thought we were all mature developers here at SO and I didn't have to spoon feed and over communicate... sigh... – dferraro Mar 22 '10 at 15:29
  • 3
    @dferraro: No, we didn't know what you mean; that's why we clarified! A lot of people come to SO with incorrect assumptions, so the smartest course of action is usually to figure out what those assumptions are first. We have no idea what you believe or don't believe without asking first, so we do. – John Feminella Mar 22 '10 at 15:34
  • 1
    I guess I see your point. Maybe I'm just a bit aggrivated at the fact I started this thread into the 900's of rep and came back monday to see im under 500. How the hell could that happen? I only have a few downvotes that I think I've always had. Did I piss off the SO gods or something?? lol – dferraro Mar 22 '10 at 16:27
  • 3
    @dferraro: There was a reputation recalculation recently to favor answers over questions. You can read more at blog.stackoverflow.com. – John Feminella Mar 22 '10 at 17:19
  • 6
    @dferraro: I apologise for the typo and my unprofessional immaturity. Thank you for setting the example. – Jeff Yates Mar 22 '10 at 17:48
  • 1
    It's only legitimate because the whole WinForms concept is badly designed. Partial is evil. – František Žiačik Feb 02 '11 at 09:44
  • I met with the `partial` class concept only recently and my first reaction to it was also very negative. But after reading this post; it's not that bad after all, if used fairly, and all files defining a partial class is kept together only. Please give me your opinions about using `partial` for keeping all static member of a class separated from instance members? – rineez Jul 13 '12 at 05:24
  • This is very old, but we just got done creating a code generator and using partial classes helped us always refresh our data classes and keep our constructors separate. Very useful – Steven Combs Oct 24 '13 at 14:42
14

There are two reasons that I would (and do) use partial classes.

  1. To separate auto-generated portions of the code (such as WinForms designer code or T4 output).
  2. To allow nested types their own file while still achieving the encapsulation required by your design.

Update
I can see that some are not convinced about my second point, so let me give an example; the ListViewItemCollection in the framework. It is quite rightly nested under ListView because it is only for use by ListView, but to make maintenance much easier, I would give it it's own file by using partial classes. I don't see this as bad design or a misuse of the partial keyword.

For more discussion, check out the question that this one duplicates: Partial Classes in C#

Community
  • 1
  • 1
Jeff Yates
  • 61,417
  • 20
  • 137
  • 189
  • 2
    I also used partials for the second reason. – Dykam Mar 19 '10 at 14:44
  • hmm... never thought of this before, using it for a nested class. But I digress... how often are nested types very complicated. In fact 2 classes should both be simple enough to fit in one file IMO! =P – dferraro Mar 19 '10 at 14:55
  • It happened to me quite a lot that I need classes which inherit the parent class, and only differ in functionality. The parent class exposes methods returning it's own type. – Dykam Mar 19 '10 at 15:31
  • 1
    @dferraro: "how often are nested types very complicated?" I have seen a custom collection class where the nested Enumerator class worked a lot of magic. It was not small. Otherwise, I agree, 99% are simple. – kevinarpe Feb 27 '13 at 12:09
11

Another legitimate use of partial classes is to help reduce the "monolithic web service" clutter in WCF. You want to to break it down into logical groups of functionality but don't want to have to create a ream of individual service instances/endpoints (presumably because they share state, resources, and so on).

The solution? Have the service implement multiple interfaces, and implement each interface in its own partial class. Then map different endpoints in the configuration to the same physical implementation. It makes the project a lot more maintainable, but you still only have one physical endpoint.

In some cases I'd point to this type of approach as a poor practice on account of the SRP, but when you're working with WCF services or web services in general, it's not quite so simple. You have to balance internal design requirements against external consumption requirements.

Aaronaught
  • 120,909
  • 25
  • 266
  • 342
  • Just what I was looking for. I was considering splitting up my service and adapter files into 1 per operation (for merging and separation reasons). – Sellorio Jul 30 '13 at 22:58
  • This thread was really making me get concerned about breaking my huge WCF service up into different files with partials. If I added more endpoints it would add complexity and I would think it would have some performance cost. I don't see any other way around it. Is there? – Joel McBeth Jul 09 '15 at 14:22
7

One less common use might be to split up a huge class into separate physical files to make life easier from a source control point of view. I've just joined a project containing some enormously bloated web service classes running to thousands of lines of code and with methods related to several different business functions.

Merging from various feature branches is a nightmare due to different teams making simultaneous unrelated changes in the same file. I can't split the web service up without making some seriously breaking changes, but breaking the class up into partial classes preserves the behaviour exactly, and removes a whole bunch of merging issues.

I'm definitely not encouraging the above as a design choice, but it was a nice quick win for us, and goes to show that partials aren't evil all the time...

Jon M
  • 11,669
  • 3
  • 41
  • 47
  • 1
    They are, arguably evil, in the way that things that make it possible to make very very bad decisions are evil. If they helped you manage huge classes, they are also enabling people to write huge classes which they otherwise might be prevented from doing. – jwg Jan 25 '13 at 09:08
  • 1
    Just what I was looking for. I was considering splitting up my service and adapter files into 1 per operation (for merging and separation reasons). – Sellorio Jul 30 '13 at 22:59
  • I agree. Sometimes you can't refactor a huge class so being able to work with it by splitting it into smaller files can be helpful. Source control is a good example, and another is the system load a huge file can put on a non-optimal developer machine. With a few plugins a multi-thousand line file in c# can be extremely slow to work with. – user1568891 Apr 26 '16 at 15:34
4

I've used partial classes in many different ways in the past. As I learn more about programming and in particular the concept of "favor composition over inheritance" I can easily see the need diminishing for both vertical inheritance and overuse of partial classes.

Other than auto-generated code, I cannot think of good use of partial classes. Even if you use EF, and need different metadata, they don't even recommend using partials for metadata. In fact if you try to duplicate any properties in another partial(just to add metadata) you'll get a compiler error.

The more we learn about refactoring and SOC (Separation of Concerns) the smaller and more focused our classes become. They are by default, re-used, which over time makes them bullet-proof and easily tested. Just say NO to gargantuan programs. Henry Ford learned this concept in the early 1900's programmers started learning it 100 years later.

Use composition when you can...

JWP
  • 6,672
  • 3
  • 50
  • 74
2

Can you explain to me when there would be a legitimate reason to ever use a partial class?

Recent versions of Visual Studio use partial classes to seperate the auto-generated designer code from your own code..

An ASP.NET example:

  • Page.aspx
  • Page.aspx.cs <- Your code
  • Page.aspx.Designer.cs <- A partial class containing auto generated code.

A WinForms example:

  • Form1.resx
  • Form1.cs <- Your code
  • Form1.Designer.cs <- A partial class containing auto generated code
Simon Bartlett
  • 2,010
  • 14
  • 15
  • 1
    But this isn't *explicitly* using them - it's all behind the scenes. I believe that the intent of the question was to determine a time when you would do so outside of the automatic behavior of the development environment. – David T. Macknet Oct 08 '10 at 14:36
2

I fully agree with John's answer. But I would take it one step further.

  • Don't make your classes partial.

The only use of partial classes I can think of that I would consider "good design" is with automatically generated code. Any other use is almost certainly unnecessarily splitting up your class. (Actually, I can see that Jeff's second point on nested classes is possibly a valid use)

Personally I think this book you are reading sounds like bad design, however do consider that he may just be using partial classes so he can just demo part of the code little bits at a time rather than just presenting the whole class in one go.

Community
  • 1
  • 1
Simon P Stevens
  • 27,303
  • 5
  • 81
  • 107
2

I've used partial classes to "physically" separate static data access methods from business class properties and methods in an active record architecture. For example, we had Company and CompanyData partial classes side-by-side. The advantage was that one file was the POCO and the other contained only data access methods. This was a stepping stone to removing data access to repository classes in a legacy application. I think that was a legitimate use, it certainly made the re-factoring process saner.

Jamie Ide
  • 48,427
  • 16
  • 81
  • 117
2

Another good use for partial classes would be when implementing the Abstract factory pattern. Make the root factory object partial and then place the actual factory methods in the same file as the class the factory instantiates.

EDIT: Partial classes also work well for classes that interact with a configuration file. Place the code containing the configuration parameters near the code that actually uses the configuration parameter.

Robert Davis
  • 2,255
  • 2
  • 21
  • 21
2

Just stumbled across this thread while googling the benefits of partial class. I am in the process of converting a Java EE application into a silverlight based .NET one. I came across the following code in the view layer :

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.225
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

...

 public partial class Wwcusts04d : System.Windows.Controls.Page {

Now, if the partial page itself is autogenerated, what's the use of maintaining it ? Also, the code inside just links various controls to their names. I don't confess to have knowledge of silverlight, but isnt this thing better suited in xaml?

Arjan Tijms
  • 37,782
  • 12
  • 108
  • 140
1

Partial class exists in the .Net framework solely to let Visual Studio designers (e.g. the Asp.Net designer and the Windows Forms designer) to generate code / mess with your classes while keeping that generated code in a separate file.

(See .NET Partial Classes vs. Inheritance)

If you do something similar (generate code that needs to coexist with user-written code) then you might also find partial classes useful, but I don't believe that Microsoft ever intended partial classes as a language concept to be useful to anyone other than the Visual Studio team.

Its not so much that using Partial classes is bad design - its just you probably wont find a use for them.

Community
  • 1
  • 1
Justin
  • 84,773
  • 49
  • 224
  • 367
  • @Kragen: Microsoft Patterns and Practices use partial classes in, for instance, the Web Service Software Factory (http://codeplex.com/sf). It is used here to separate generated from hand-written code. They are also used by DSLs generated by the DSL Toolkit. – John Saunders Mar 19 '10 at 14:16
  • 4
    -1 for **solely** emphasis. It was a feature important enough to change the grammar of C#; that at least implies that there was more than one reason. – Robert Davis Mar 19 '10 at 15:42
  • @Robert - there is a blog / article somewhere from a Microsoft developer about the design of partial classes. I'll try and find it... – Justin Mar 19 '10 at 15:49
  • See my answer, above, for where they've been incredibly useful. – David T. Macknet Oct 08 '10 at 14:32
1

I've used a partial class twice in VB.Net, and both times were for the rare occasion that I needed late binding. Simply create a partial class and turn Option Strict Off at the top.

Jules
  • 4,319
  • 3
  • 44
  • 72
  • Can you provide a code snippet for this? Also: couldn't you have simply declared whatever variables as `Object` rather than whatever you've done? – David T. Macknet Oct 08 '10 at 14:35
  • There's an internal control called PropertyGridView which is part of the PropertyGrid control. You can access this by using the Controls collection property of the PropertyGrid. In the PropertyGridView is a Public property called GetScrollOffset. By treating the PGV as an object, with option Strict off, I can get hold of the scroll offset. ie. pgv as object = pg.Controls(2); (strict off); scrollOffset = pgv.GetScrollOffset. – Jules Oct 12 '10 at 18:25
1

Just to add on to the previous answers that mentioned separating generated code from custom code, I've found partial classes useful for extending strongly-typed datasets.

Scott Lawrence
  • 6,993
  • 12
  • 46
  • 64
1

There's a lot of discussion out there on this topic, and lots of people saying that 1) it's bad design to use partial classes, 2) that it's used for autogenerated code, and 3) that it shouldn't take the place of inheritance.

I have a situation, though, in which partial classes look like they'll come in very handy: I'm building a series of applications which will eventually be integrated into a suite. They'll all have a main form which will provide some functionality, and several shared components (e.g., a form to display reports). While I could define a base class and inherit from it, that would mean a lot of rework when the time comes to combine all of the applications into the "enterprise" version of the product.

Thus, partial classes are quite useful, because I can quite simply include the various partial classes into the combined version, while still allowing me to build the individual, stand-alone versions of the product. If I were to try to accomplish this using inheritance, I'd end up with each component calling its own version of the common components (e.g., InvoiceReportViewer, PurchasingReportsViewer, etc.) rather than simply calling ReportsViewer and knowing that Visual Studio will have integrated all of the bits for me.

David T. Macknet
  • 3,112
  • 3
  • 27
  • 36
0

Another thing to consider, partial classes forces you to create different file names which contains same class name. For example you have FactoryClass and you are creating partial versions of it like; Factory.designer.cs, Factory.data.cs and all those files has class named FactoryClass.

If you navigate to this question; there is a best practice defined as:

Best practice, however, is to define one class per file and to give the file the same name as the class (or struct, etc.) being defined.

Community
  • 1
  • 1
Teoman shipahi
  • 47,454
  • 15
  • 134
  • 158