#638 – Defining and Using a Partial struct

In addition to classes, structs can also be partial, and contain partial methods.  Just like partial classes, a partial struct is one that is split across multiple files.  A partial method in a partial struct is a method that is declared in one portion of the struct and, optionally, implemented in another.

Like a partial method in a class, a partial method in a struct is implicitly private.

    // Dog-1.cs
    public partial struct DogDimensions
    {
        public double Height, Width, TailLength;

        partial void CustomPrintDimensions();
    }

 

    // Dog-2.cs
    public partial struct DogDimensions
    {
        partial void CustomPrintDimensions()
        {
            Console.WriteLine(
                string.Format("Dog is {0} in high, {1} in wide, and has a tail that's {2} in long",
                    Height, Width, TailLength));
        }

        public void DumpDimensions()
        {
            CustomPrintDimensions();
        }
    }

 

            DogDimensions dims;
            dims.Height = 14.0;
            dims.Width = 8.0;
            dims.TailLength = 24.0;
            dims.DumpDimensions();

#637 – A Delegate Can Refer to A Partial Method

You can have a delegate refer to a partial method, but only if the partial method is implemented.  At compile-time, if a delegate points to a partial method and you’re compiling only the declaration of the partial method, but not an implementation, you’ll get a compiler error.

    // Dog-1.cs
    public partial class Dog
    {
        // Action is a delegate type in System that takes
        //   no parameters and returns a void
        Action barkDelegate;

        public Dog()
        {
            // Point delegate to partial method Bark.
            barkDelegate = Bark;
        }

        public void BarkViaDelegate()
        {
            barkDelegate();
        }

        // Partial method declaration--no implementation here
        partial void Bark();
    }
    // Dog-2.cs
    public partial class Dog
    {
        // Implementation of Bark
        partial void Bark()
        {
            Console.WriteLine("Woof!");
        }
    }
        static void Main()
        {
            Dog d = new Dog();
            d.BarkViaDelegate();
        }

#636 – The Reason for Partial Methods

Partial methods allow one portion of a class to declare one or more methods and then another portion of the class, in a different file, to optionally implement one or more of those methods.

You’ll typically see partial methods used when some tool generates a portion of a class and the user (developer) is expected to develop the remainder of the class.  The class in question is a partial class, because it is split across two (or more) files–the tool-generated part and the user-generated part.

Using partial methods, the tool-generated code can declare a number of optional methods that are basically extensibility points for the user-generated code.  The tool-generated will call these methods, but only if the user decides to implement them.  If the user does not implement them, they are simply not called.

#635 – Limitations on Partial Methods

There are a few limitations on the use of partial methods.  A partial method

  • Can’t have access modifiers, but is implicitly private
  • Can’t be virtual and can’t override or replace a virtual method in a base class (can’t use keyword virtual, new or override)
  • Can’t be sealed
  • Can’t be abstract
  • Can’t be marked as external with the extern keyword
  • Must have a return type of void
  • Must not have any out parameters
  • Can’t directly implement an interface method (since interface methods are public)

#634 – Invoking Partial Methods That Have No Implementation

partial method is a method declared in one portion of a partial class and implemented in another.  You can also declare a partial method in one place, but not provide an implementation.

What happens, however, if the class that includes the partial method declaration includes a call to the partial method, but then you never provide the implementation?

For example, assume that we declare Dog.Growl as a partial method in the following file, but then never provide an implemenation of Growl.

    public partial class Dog
    {
        public void BeAggressive()
        {
            Console.WriteLine("Woof");

            // Invoke partial method
            Growl();

            Console.WriteLine("Done being aggressive");
        }

        // Partial method declaration--no implementation here
        partial void Growl();
    }

If you compile this and your code does not include an implementation for the Growl method, the compiler does not complain. It just quietly removes the call to the Growl method.

#633 – The Implementation of A Partial Method Is Optional

A partial method is a method declared in one portion of a partial class and implemented in another.

    // Dog-1.cs
    public partial class Dog
    {
        public string Name { get; set; }

        // Partial method declaration--no implementation here
        partial void Growl();
    }

One interesting thing about partial methods is that implementing them is optional.  In other words, you may provide an implementation of the Growl method shown above, in a separate file containing additional implementation for the partial class Dog.  But the compiler won’t complain if you never provide an implementation for the Growl method.