July 28, 2007

C# Parital Methods

Update: Orcas Beta 2 is out, and I found a problem in my syntax. Now fixed.

I was just looking through the Orcas Beta 1, and I saw something I have been waiting to talk about...Partial Methods!

This allows you to create a method sub in a partial class so you can provide the implementation in another partial class.

A case where I would use this: in code generation. You generate a data object as a partial class. Now say you want to customize the constructor a bit more. Current you have to use inheritance to do that -- but then you have to remember to use the inherited class and not the generated calss. But with partial methods you can use the main class and provide that logic. Also, if the partial method is not implemented in the other partial class, it is taken out by the compiler. Nice.

A second use: logging. You can stub out methods where you would like logging to occur, but you don't want the partial class to have to deal with the implementation of logging, making it easier to switch out later.

I hope you see why I am excited about this enhancement.

A couple of caveats though,
  1. the method must return void (or a sub for you VB folks).
  2. out parameters are not allowed -- but parameters are allowed in general.
  3. You are not allowed access to internal/private members
  4. They can only be defined and implemented in a partial class.

Below is a stub implementation:

// my generated class in file1.cs
public partial class Class1
{
// a partial method
partial void CalledByInit();

public void Init()
{
CalledByInit();
}

}

// my implementation class in file2.cs
public partial class Class1
{
public void CalledByInit()
{
// do my stuff here
}
}

Now why is this better than:
1. just declaring a delegate in the middle of your class?
2. passing in the code as a predicate parameter?

The answer:
1. A delegate can be assigned by anyone, and potentially have multiple implementations. That isn't always good. The partial method can only have one implementation and only by other partial class.
2. aesthetically that makes a really ugly call, plus it requires that the caller have intimate knowledge of the workings of the method that it shouldn't have to have. Now you can localize that knowledge in one place.

Again, thing about the main use case for the partial method: it should be used in conjunction with code generators. If any of you have used SubSonic, Typed Datasets, NHibernate, or other technologies, right now you are using a mixture of inheritance and partial classes. With this you might be able to drop the inherited class all together. And frankly, I'm for anything that reduces the number of classes lying around a project.

If you are interested in other new features in C# 3.0 I found a nice Power Point from Raj that you can check out.

Partial Methods are mentioned on LukeH's blog.
And they are talked about on the VB Team blog.

No comments: