Johnson
Johnson

Reputation: 421

Partial Methods in C# Explanation

I am having a hard time understanding the usage of partial methods.

Can you provide an example that doesn't have to do with LINQ or that sort of database things?

Are partial methods the same things like when we are in the WinForms and coding behind it, if we use a method, it gets compiled, but if we don't, then it gets removed by the compiler? Is that correct?

Upvotes: 26

Views: 13866

Answers (3)

Matt Burland
Matt Burland

Reputation: 45135

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.

Upvotes: 38

Frederic
Frederic

Reputation: 1810

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.

Upvotes: 8

Benjamin Basmaci
Benjamin Basmaci

Reputation: 2557

As addition to Matt Burlands answer Johnsons followup question in the comments of that answer:

I have never created them myself but few small uses come to mind for me:

  • Using partial methods to craete something similar to abstract classes or interfaces. basically, having "optional methods" would be possible this way, making it able to remove method implementations without having to remove their respective calls and reimplementing it eventually
  • Using partial methods to be able to build multiple projects with different implementations on the same base. You could have a build process that allows you to choose between different implementations, that are reflected in the different partial classes. The "base class" would have the method signatures and the different "implementation calsses", "implementA.cs" and "implementB.cs", would have different implementations. That way, you could for example create Develop- Test- and Releaseimplementations or User1- User2 and User3 implementation. Cool thing about that would be that you dont have to destinguish these things on runtime. Instead you would be able to distribute "clean" versions that are already specified to that degree.

I would also point out to differences that might be an alternative to what you are trying to acheive with the partial methods.

  • Events - partial methods can be used like events. If they are not implemented, they are ignored (they are not even in the compilation result). But there is a difference to events. While you can have mutliple handlers for one event, you can only implement a partial method ONCE!
  • Abstract classes and Interfaces - partial classes/methods can be used like abstract classes without having to implement a method and leaving it empty. If you know that this will happen often with a given abstract class (first check your architecture obviously, it might be flawed) you could use partial methods instead

Another use might be to provide base functionality to someone. You can do that what I would call "bottom up", meaning you craete something and people use it as a base, building on top of it, using it like tools. Or you could provide it "top down". Meaning, that you already implemented the way the components work together, but someone else might define what exactly those components do internally e.g. I want to build a table and I already implemented that its a plate with four legs but I leave it to the user to choose waht form the legs have. This is often used with generated code to write generated and semf-made code in one class but in different .cs-files.

ATTENTION

All of that being said, those are probably not the best ways to acheive those goals. There are multiple ways to do those things that dont need partial methods and might be better suited for what you want to do. But maybe these give you an idea on how partial methods might be used. It really depends on what you need to do but knowing hw partial classes work might be useful in the future.

Upvotes: -1

Related Questions