Skip to main content
Redhat Developers  Logo
  • Products

    Platforms

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat AI
      Red Hat AI
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • See all Red Hat products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat Developer Hub
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat OpenShift Local
    • Red Hat Developer Sandbox

      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Red Hat OpenShift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • See all technologies
    • Programming languages & frameworks

      • Java
      • Python
      • JavaScript
    • System design & architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer experience

      • Productivity
      • Tools
      • GitOps
    • Automated data processing

      • AI/ML
      • Data science
      • Apache Kafka on Kubernetes
    • Platform engineering

      • DevOps
      • DevSecOps
      • Red Hat Ansible Automation Platform for applications and services
    • Secure development & architectures

      • Security
      • Secure coding
  • Learn

    Featured

    • Kubernetes & cloud native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • AI/ML
      AI/ML Icon
    • See all learning resources

    E-books

    • GitOps cookbook
    • Podman in action
    • Kubernetes operators
    • The path to GitOps
    • See all e-books

    Cheat sheets

    • Linux commands
    • Bash commands
    • Git
    • systemd commands
    • See all cheat sheets

    Documentation

    • Product documentation
    • API catalog
    • Legacy documentation
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore the Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

C# 8 default interface methods

March 3, 2020
Tom Deseyn
Related topics:
.NET
Related products:
Red Hat OpenShift

    In the previous articles, we discussed C# 8 async streams and pattern matching. In this article, we’ll look at C# 8 default interface methods.

    Extending interfaces

    Before C# 8, it was not possible to add members to an interface without breaking the classes that implement the interface. Because interface members were abstract, classes needed to provide an implementation. C# 8 allows us to extend an interface and provide a default implementation. The runtime (which also needs to support this feature) uses the default implementation when the class does not provide it:

    interface IOutput
    {
        void PrintMessage(string message);
        void PrintException(Exception exception)
            => PrintMessage($"Exception: {exception}");
    }
    class ConsoleOutput : IOutput
    {
        public void PrintMessage(string message)
            => Console.WriteLine(message);
    }
    

    In this example, ConsoleOutput does not provide an implementation for PrintException. When PrintException is called against a ConsoleOutput instance, the default method from the IOutput interface will be called. ConsoleOutput might provide its own implementation.

    A derived interface can provide a more appropriate default implementation by explicitly implementing the base member:

    interface IA
    {
        void M() { WriteLine("IA.M"); }
    }
    interface IB : IA
    {
        void IA.M() { WriteLine("IB.M"); }
    }
    

    We explicitly implement the base member by including IA. in the name. Without IA., the compiler would warn us to either make it explicit, or use the new keyword if we want to hide it.

    C# 8 allows us to add static members in the interface that can be used by the default interface members:

    interface IOutput
    {
        private static string s_exceptionPrefix = "Exception";
    
        public static string ExceptionPrefix
        {
            get => s_exceptionPrefix;
            set => s_exceptionPrefix = value;
        }
    
        void PrintMessage(string message);
    
        sealed void PrintException(Exception exception)
            => PrintMessage($"{s_exceptionPrefix}: {exception}");
    }
    

    This example shows a private static field and a public static method to implement the ExceptionPrefix property that's used by the sealed PrintException method. By adding the sealed keyword, this method can no longer be overridden.

    Code inheritance

    C# supports inheriting from a single-base class and implementing multiple interfaces. Until C# 8, only the base class could provide code that is usable by the derived class. With C# 8, interfaces can provide code to their implementing classes.

    In addition to that enhancement, we can use access modifiers on members and provide static members:

    interface IOutput
    {
        sealed void PrintException(Exception exception)
            => PrintMessageCore($"Exception: {exception}");
    
        protected void PrintMessageCore(string message);
    
        protected static void PrintToConsole(string message)
            => Console.WriteLine(message);
    }
    
    class ConsoleOutput : IOutput
    {
        void IOutput.PrintMessageCore(string message)
        {
            IOutput.PrintToConsole(message);
        }
    }
    

    In this example, we see that the IOutput interface delegates the PrintMessageCore implementation to the derived class and provides a sealed implementation of PrintException that makes use of PrintMessageCore. The example also shows how the static protected PrintToConsole method can be called from a derived type.

    This setup allows us to include the code that is common with the interface, allowing different classes to share this code without a common base class and thus enabling multiple inheritance and trait patterns.

    C# 8 allows sharing code, but interfaces are still not allowed to have instance fields (state). Interface methods that require state either need to be abstract (so they are implemented in the class), or they need to accept the state as an argument (provided by the caller, like the implementing class). This approach avoids the inheritance diamond problem for state. For code, the diamond problem is solved by the compiler requiring additional members in ambiguous cases (which can then call the appropriate base).

    Conclusion

    In this article, we looked at C# 8 default interface methods. Default interface methods provide a way to extend interfaces with new members without breaking previous implementers. The new features also allow code to be shared between types, which enables multiple inheritance and trait patterns. In the next article, we will look at nullable reference types.

    C# 8 can be used with the .NET Core 3.1 SDK, which is available on Red Hat Enterprise Linux, Fedora, Windows, macOS, and other Linux distributions.

    Last updated: February 22, 2024

    Recent Posts

    • Automate VM golden image builds for OpenShift with Packer

    • Setting up Intel TDX VMs with Trustee on OpenShift

    • Building and running Request Tracker as a quadlet container

    • Use OpenShift Lightspeed with locally served LLMs to drive security-focused, cost-efficient enterprise solutions for Red Hat products

    • 3 MCP servers you should be using (safely)

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Platforms

    • Red Hat AI
    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Build

    • Developer Sandbox
    • Developer tools
    • Interactive tutorials
    • API catalog

    Quicklinks

    • Learning resources
    • E-books
    • Cheat sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site status dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2025 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue