Partial Methods in C# Explanation

When you have a partial class, you can define the signature of a method in one file and have the implementation in another. That's a partial method.

So in one file you have:

partial class Foo
{
    partial void Bar();  // no implementation

    public void DoSomething()
    {
        // do some stuff...
        Bar();    // this will be removed if Bar isn't implemented in another partial class
        // do something else...
    }
}

And in another you have

partial class Foo
{
    partial void Bar()
    {
        // do something...
    }
}

This lets the first file call Bar without worrying about whether or not Bar is implemented. If Bar is not implemented somewhere, then calls to it are removed (from here):

Partial methods enable the implementer of one part of a class to define a method, similar to an event. The implementer of the other part of the class can decide whether to implement the method or not. If the method is not implemented, then the compiler removes the method signature and all calls to the method. The calls to the method, including any results that would occur from evaluation of arguments in the calls, have no effect at run time. Therefore, any code in the partial class can freely use a partial method, even if the implementation is not supplied. No compile-time or run-time errors will result if the method is called but not implemented.

A partial method must return void, else it'd be unsafe to remove all method calls should the method not be implemented:

Partial method declarations must begin with the contextual keyword partial and the method must return void.

As with partial classes, the main use is working with generated code:

Partial methods are especially useful as a way to customize generated code. They allow for a method name and signature to be reserved, so that generated code can call the method but the developer can decide whether to implement the method. Much like partial classes, partial methods enable code created by a code generator and code created by a human developer to work together without run-time costs.

So you might have generated code that makes a call to a partial method (defined without implementation in the generated code) and you are free to extend that partial class and implement that partial method if you want / need to.


Here is an example I have used in my own programming... As a teacher and I often provide code samples to my fellow students. However I want them to realize their coding project one step at a time, making it more and more complex as time goes by. More specifically, suppose I provide them with the code to run a menu to test and drive a class they need to implement. On step 1, the menu is simple. And then with every new step, more menu items are added to tests more and more class functionalities. Therefore, initially, I provide them with a single file enacting a simple menu and then as they progress toward a complete solution, I provide them with more files to drive and check their new programming. This could be done that way:

// --- File MenuStep1.cs ---
partial class Menu
{
    // This array is populated with more and more items at every new steps
    readonly List<MenuItem> MenuItems = new List<MenuItem>();

    public void Show()
    {
        // Code to show menu here
    }

    // Suppose we have a Main here, but that's not necessary
    public static void Main()
    {
        new Menu().Show();   
    }

    // These are hooking methods to add menu items later
    partial void InitStep2();
    partial void InitStep3();
    partial void InitStep4();

    public Menu()
    {
        InitStep1();
        InitStep2();
        InitStep3();
        InitStep4();
    }

    void InitStep1()
    {
        // Code that adds menu items, but only for step 1
    }
}

Note that since the partial methods InitStep2, 3 and 4 are not defined yet, they wont be called (and they wont even be compiled in). Later I provide them with files that automatically extends the menu as follow:

// --- File MenuStep2.cs ---
partial class Menu
{
    partial void InitStep2()
    {
        // Code that adds more menu items
    }
}

,

// --- File MenuStep3.cs ---
partial class Menu
{
    partial void InitStep3()
    {
        // Code that adds more menu items
    }
}

Etc.