AspAlliance.com LogoASPAlliance: Articles, reviews, and samples for .NET Developers
URL:
http://aspalliance.com/articleViewer.aspx?aId=1536&pId=-1
Understanding and Using Partial Classes in C#
page
by Brendan Enrick
Feedback
Average Rating: 
Views (Total / Last 10 Days): 80056/ 220

Introduction

One great addition to C#, (also added into VB, but I don't cover that much here) introduced with the .NET Framework 2.0, is support for partial classes. This is a very powerful tool made available to developers. It allows you to have multiple pieces of a class definition. Functionally, partial classes are not at all different from classes written as full classes. Which means you can have one single class definition or a class written as a few distinct parts, so you need not worry about partial classes breaking existing functionality.

If you've done any ASP.NET work since 2.0 you've probably already seen partial classes. Perhaps you did not know you were working with them, but with ASP.NET sites every page created is actually using partial classes. The other part of the partial class is created from the .aspx file.

How Partial Classes Work

The basic idea of a partial class is very easy to understand. You keep the definition of a class split into pieces. During the compilation of the code, the compiler will finds all of the pieces of the class and lump them together. This task accomplished by the compiler removes that separation, so functionally there is no difference between a class made of partial classes and a whole class.

This is great because it means that we get the benefits of being able to develop applications using partial classes without fear of it having any affect on the functionality of the code we write.

Creating Partial Classes

As I've mentioned, partial classes allow you to separate code for a class into multiple class definitions. So as an example I will write a few class definitions. One will be a whole definition of a class without using partial classes, and the other one will be the same class split into two partial classes. Observe here my single definition class of AIPlayer.

Listing 1: A Standard Class

public class AIPlayer
{
  public AIPlayer()
  {
    // Construct your class here.
  }
  public Move GetMove()
  {
    // Choose the best move and return it.
  }
}

In this simple example I've defined a basic constructor as well as one simple method. Not much, but we don't need to have a lot for our example here. The important thing to note here is the possibility to create these classes and how they work. So notice on the next one how we will separate these two methods, the constructor and the GetMove function, into two separate class definitions.

Listing 2: A Class Split Into Two Partial Classes

public partial class AIPlayer
{
  public AIPlayer()
  {
    // Construct your class here.
  }
}     
public partial class AIPlayer
{     
  public Move GetMove()
  {
    // Choose the best move and return it.
  }
}

Without having the partial keyword in there I would probably get a compiler error. The reason for this is that I would be declaring two different classes in the same namespace with the same name, and that would generate the error. Since I have the partial keyword there, the compiler knows that I am just extending the existing class. It will take that into account and will combine the code before trying to compile it.

As a note, make sure to use the partial keyword on ALL definitions of the class even the original one. This is not necessary for VB, but in C# all of the classes must have the partial keyword. I think it is great that this is included, because it is a hint to a programmer that there might be another piece of a class somewhere else. If you ever see the partial keyword on classes you're working with, it is a nice warning that there might be more to the class elsewhere.

When to Use Partial Classes

There are plenty of cases where a partial class can assist you in developing your applications. Most people have already seen them and might not have noticed them in ASP.NET pages, because you don't actually need to know that it is using these partial classes in order to use them. They're also quite popular being used alongside generated code, because it lets people modify the generated code. Sometimes people will also use it when working in larger groups who will not be committing code often. This is because it lets them make large amounts of changes without having painful merges later.

ASP.NET Pages Already Use Partial Classes

First I will remind you again of the ASP.NET pages. Every page you create in ASP.NET is eventually compiled. Every .aspx file will be used to declare a page class. They all inherit from a standard Page class. You can see this in your code behind file. If you view the code of your ASP.NET page you will see a class definition. It will have the partial keyword in the definition and it will look similar to this code.

Listing 3: Codebehind File

public partial class MyWebPage : System.Web.UI.Page
{
  protected void Page_Load(object sender, EventArgs e)
  {
    // Perform some action here.
  }
}

Since there will be a class created from your ASP.NET code in the .aspx file this must be a partial class. This brings up one of the best uses of partial classes. You should use partial classes when you want to write code for a class which is auto-generated. Since the code for the page class is generated for you, it is important to keep your code separate. This means that a partial class is perfect, because it keeps the code physically but not logically separate. Being in a separate file means the auto-generating process will not kill your code and the compiler will still know to add in your code before it compiles the code.

Working with Generated Code

Some developers use software to generate code for them, and this will let them modify the code for their own purposes without making changes to the generated code. I use LLBLGen, and it generates a ton of code for me. When I need to make modifications I can't go in and edit the files it creates, because the next time I generate the files my changes will disappear. Instead I create a new file for each class I want to extend. I then add in the definition for a partial class. This file I have created will not be overwritten by LLBLGen since LLBLGen didn't create the file, and the compiler will still make sure that my code is compiled into the class.

Alongside generated code is likely the most common place where partial classes are used. Since ASP.NET pages use it, and it works so well it just makes sense to use partial classes with generated code. If you ever find generated code which is not using partial classes, make sure to mention to the person, group, or company who made the generator about your request that the classes be written as partial classes. It will make your code better organized, easier to work with, and safe from being overwritten.

Multiple Developers Working On the Same Classes

It gets annoying sometimes when writing code with multiple developers. If the developers will be working without or with minimal source management this can be very necessary. I often run into problems having to merge changes with other people. This happens because most developers I know add new code to the bottom of the file. This is probably because it is easy to add code there without having to think about placement. It gets annoying after a while when everyone does this, and sometimes merging tools get confused and I end up merging by hand anyway. I've even had auto-merge make mistakes when merging and I've obtained code which does not compile. Sometimes it is easier to just have partial classes for this. This does add a small maintenance headache, and you might be thinking that it becomes difficult to find the correct code. I never have a problem finding the correct code in the file, and this is because of a little tool we all know and love. It is called "Go To definition". For those of you who somehow missed this important tool I've included a nice screenshot. Just right click on the named piece of code and you will see these options. Click on "Go To Definition".

Figure 1: Go To Definition

I really hope that everyone knows how to do this already. If you don't know how to use this feature then you should learn it quickly. Your life will become much better. When you use this you will not need to remember where the code is because Visual Studio will take you directly to the location you want.

When you're working with multiple people and not using a versioning system often, it becomes quite difficult to manage the changes without painful merges. As long as you're not working on tightly knit code, it is easier to just keep the code in separate files. Sure, files become a little bit more of a pain to manage, but it is very nice to not have to merge changes in files after extensive changes in the code.

Implementing Multiple Interfaces with Partial Classes

When you need to implement multiple interfaces, the best way to do this is by using partial classes. If you don't know what interfaces are or how to use them I recommend reading my article which describes how interfaces work and how to use them.

For each interface your class should implement you will have certain code you need to write. When I implement an interface, I will place the code for the interface implementation in a region block. This gives me a small sense of code separation. When implementing multiple interfaces you will want to separate the code for this into separate files and declare the class as partial. This will give you great separation of the interface code and the core class code. This is not very important with just one interface, but if you're going to have more than one it becomes a necessity.

This is a nice solution because you are able to keep each individual interface on a different partial class, and have your core class methods stored in its own partial class as well. This will let you keep the class nice and clean without having to have the extra code from the interfaces in the same file as the code for the class. A lot of times the code for the class is something unimportant to the core functionality of the class. As an example, if you were writing something with the IDisposable interface, the IDisposable data has nothing to do with the rest of your class. This is just code dealing with how to dispose of the class. Since this is the case, when writing the core logic of the class you don't care about the IDisposable data, and if you have another interface you don't care about that one either when writing the code of the class. It is usually an external capability of the class which is not involved in the main functionality of the class.

Partial Interfaces and Structs

The partial keyword is not limited to just classes. It may also be used for interfaces and structs. When you're creating an interface or a struct you might also want to have the code separated. You declare a partial interface or a partial struct the same way as the partial class. You simply add in the keyword partial. The following code shows how to declare a simple partial interface and a simple partial struct.

Listing 4: Simple Partial Interface

public partial interface IPlayable
{
  Move GetMove();
}

This is just one partial interface defined here. We might have another piece located elsewhere. This is a very simple interface and it is obviously for my AIPlayer I listed above.

Listing 5: Simple Partial Struct

public partial struct Move
{
  public int column, row;
      
  public Move(int c, int r)
  {
    column = c;
    row = r;
  }
}

We use these the same way we use partial classes, and for the same reasons. Make sure that you're always using the partial keyword for every definition of the class, interface, or struct. You will probably less often need to use interfaces and structs as partial, but if the need arises now you know. You'll be able to create these as partial and allow for more maintainability in your code.

References
Conclusion

Partial classes should make your coding easier. They will allow for some extra code separation without adding much complexity. They will also allow you to work with generated code without fear of changes being overwritten. Plenty of different applications which generate code for you will declare classes as partial specifically so that you can do this. They make it much easier for people to work with the generated code if the class is declared as partial. If you're ever writing any sort of a code-generating program you will want to make sure that you declare all classes, interfaces, and structs as partial. The users of your program will thank you when they need to make modifications. No your code is not perfect, so some users will want to make modifications.



©Copyright 1998-2014 ASPAlliance.com  |  Page Processed at 4/24/2014 2:41:50 PM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search