User Tools

Site Tools


notes:csharp:interfaces

Interfaces in C#

Simple Examples

Example: A simple interface definition:

interface IBook
{
    string GetSummary();                    // method
    int Rating { get; set; }                // property
    event EventHandler BookUpdated;         // event
    string this[string isbn] { get; set; }  // indexer
}

Example: Define a 'set' accessor when implementing an interface on a class:

interface ICategory
{
    // The interface defines only the get accessor.
    string CategoryName { get; }
}
 
class BookCategory : ICategory
{
    // The class implements both the get and the set accessor.
    // When the class is accessed through the interface, only the get accessor is available.
    // Direct users of the class see both the get and the set accessors.
    public string CategoryName { get; set; }
}

Example: Define an interface with a generic type parameter:

// we can have Message<string>, Message<Email>, Message<ForumPost>, etc.
interface IMessage<T>
{
    void Send(T msg);
    IEnumerable<T> All();
}

Explicit Interface Implementation

Explicit interface implementation allows us to provide methods (or other class members) that can be accessed only when using the interface directly.

Explicit interface implementation is useful in the following situations:

  • to create a class member that is only called through the interface
  • to hide members of a class to outside users
  • to solve name collisions of methods derived from multiple interfaces
  • to allow implementation of multiple methods that differ only by their return type

Example: Both the Account class and the ITransaction interface define the Add method. By using the explicit interface implementation, we solve the name collision and give separate implementation to each Add method. The ITransaction.Add method can only be called through the interface.

interface ITransaction
{
    void Add(decimal amount);
}
 
class Account : ITransaction
{
    // A class method accessed implicitly.
    public void Add(decimal amount)
    {
        Console.WriteLine("Account.Add {0}", amount);
    }
 
    // A method that implements the ITransaction interface explicitly. Note that we don't specify 
    // an access modifier. The methods that implement an interface are always public.
    // Explicit interface implementation is achieved by qualifying an interface method with the name of 
    // the interface.
    void ITransaction.Add(decimal amount)
    {
        Console.WriteLine("ITransaction.Add {0}", amount);
    }
}
...
// Call the Add method implemented on the class.
Account acc = new Account(); // create the Account object
acc.Add(10); // output: Account.Add 10
 
// Call the Add method implemented on the interface.
ITransaction trans = new Account(); // create an interface variable
trans.Add(20);  // run the explicit implementation; output: ITransaction.Add 20
 
// Call the Add method implemented on the interface by casting the Account object.
((ITransaction)acc).Add(20); // cast to interface

Example: We have two methods that have the same signatures and different return types. It won't compile as the method overloading does not take into account return types. This is how it may be solved using explicit interface implementation:

public class EnumerableCatalog : IEnumerable<string>
{
    // One of the methods has to use the explicit interface implementation 
    // because they differ only by their return type.
 
    public IEnumerator<string> GetEnumerator()
    {
        ...
    }
 
    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }
}
notes/csharp/interfaces.txt · Last modified: 2017/02/09 by admin