Simulating multiple inheritance in C#

by Marc Sigrist 18. February 2010 23:15

It is possible to simulate multiple inheritance in C#, in a limited way, by applying extension methods to interfaces. An example is shown below. Note that this works only for method implementation inheritance, but not for properties or any other kinds of base members.

The C# team originally considered including extension properties in C# 4.0, but then dropped the feature. The reason apparently was that including extension properties would logically imply including indexed extension properties as well, which C#, by design, does not support. However, accessing (but not defining) indexed properties will be introduced in C# 4.0, in order to make it easier to work with COM interop. Another reason might be that extension properties in C# 4.0 would cause conceptual confusion with the already-existing feature of attached properties in WPF. Interestingly, F# does offer extension properties, but it cannot be used (yet?) as code-behind language for WPF XAML files.

You probably will not use this approach in order to „simulate multiple inheritance“ very often. However, the capacity to add extension methods to interfaces, as such, is a powerful feature. It allows to cleanly separate categories of standard behaviors from their owners.

 using System;

// This test shows how to simulate multiple inheritance in C#.

// Requires .Net Framework 3.5 as target framework.

namespace Test {

    interface IBase1 { }

 

    static class Base1Implementation {

        internal static void Base1Method(this IBase1 base1) {

            Console.WriteLine("Base1Method called.");

        }

    }

 

    interface IBase2 { }

 

    static class Base2Implementation {

        internal static void Base2Method(this IBase2 base2) {

            Console.WriteLine("Base2Method called.");

        }

    }

 

    class Derived: IBase1, IBase2 { }

 

    static class Program {

        static void Main() {

            var derived = new Derived();

            derived.Base1Method(); // Writes "Base1Method called."

            derived.Base2Method(); // Writes "Base2Method called."

        }

    }

}