C# 11 Interfaces

In this chapter, we will explain what C# interfaces are, how to write your own, and how to make other classes comply with one.

Understanding C# interfaces

By default, there are no specific rules to which a C# class must conform as long as the class is syntactically correct. In some situations, however, a class will need to meet certain criteria in order to work with other classes. This is particularly common when writing classes that need to work with other libraries. A set of rules that define the minimum requirements that a class must meet is referred to as an interface. An interface is declared using the interface keyword and simply defines the methods and properties that a class must contain in order to be in conformance. When a class adopts an interface but does not meet all of the interface requirements, errors will be reported stating that the class fails to conform to the interface.

Consider the following interface declaration. Any classes that adopt this interface must include a method named ShowMessage() which accepts no parameters and returns a string value:

interface IMessageBuilder {
    void ShowMessage();
}

Note: Interfaces are usually named with “I” as the first letter to differentiate them from non-interface classes.

Below, a class has been declared which adopts the IMessageBuilder interface but fails to compile:

class Example
{
    interface IMessageBuilder {
        void ShowMessage();
    }

    public class MyMessageBuilder : IMessageBuilder {

    }
 
    static void Main()
    {
        
    }
}

When compiled, the above code will result in an error similar to the following:

main.cs(7,18): error CS0535: `Example.MyMessageBuilder' does not implement interface member `Example.IMessageBuilder.ShowMessage()'
main.cs(4,14): (Location of the symbol related to previous error)

Unfortunately, as currently implemented, MyMessageBuilder generates a compilation error because it does not contain an implementation of the ShowMessage() method as required by the interface it has adopted. To conform to the interface, the class would need to meet this requirement, for example:

class Example
{
    interface IMessageBuilder { 
        void ShowMessage();
    }

    public class MyMessageBuilder : IMessageBuilder {
        public void ShowMessage() {
            // Code goes here.
        }
    }
 
    static void Main()
    {
        
    }
}

In addition to methods, interfaces can also include data members. An important rule when working with interfaces is that variables must be declared as properties and cannot be declared as fields or constants (for a reminder of the differences between fields and properties, refer back to the lesson entitled An Introduction to C# 11 Object-Oriented Programming).

The following, for example, would generate a syntax error during compilation:

interface IMessageBuilder { 
    string myMessage;  // Fields are invalid in interfaces
    void ShowMessage();
}

Instead, the variable needs to be declared as a property as demonstrated below:

class Example
{
    interface IMessageBuilder {

        string MyMessage { get; set; } 
        void ShowMessage();
    }

    public class MyMessageBuilder : IMessageBuilder {

        private string _myMessage;

        public string MyMessage { 
            get { return _myMessage; }
            set { _myMessage = value; }
        }

        public void ShowMessage() {
            System.Console.WriteLine(_myMessage);
        }
    }
 
    static void Main()
    {
        MyMessageBuilder builder = new MyMessageBuilder();
        builder.MyMessage = "Hello Interfaces!";
        builder.ShowMessage();
    }
}

Note that  get and set accessor methods are declared but not implemented in the above interface. As interface methods, the implementation is performed in the conforming class declaration.