C# Interface

Array Class Collections File Keyword String .NET ASP.NET Cast Compression Data Delegate Directive Enum Exception If Interface LINQ Loop Method Number Process Property Regex Sort StringBuilder Struct Switch Time Windows WPF

Interface

Interface. A program has classes,
methods
and properties. What if these members could be used in a unified way? What if we could share this code?


Interface type

With interfaces, this is possible. Interfaces make programs more compact and easier to maintain. This extra complexity leads to greater simplicity.


Interface example: IPerl

We start. This program defines an interface named IPerl, which requires a Read method. It defines a class named Test. The Test class implements IPerl—it must implement the Read method.

Then:In the Main method, we create a Test instance and store it in an IPerl reference. We invoke the Read method from the interface.

Tip:When a class implements an interface, it can be used through a reference to that interface.

Based on:

.NET 4.5

Program that uses interface: C#

using System;

interface IPerl
{
    void Read();
}

class Test : IPerl
{
    public void Read()
    {
	Console.WriteLine("Read");
    }
}

class Program
{
    static void Main()
    {
	IPerl perl = new Test(); // Create instance.
	perl.Read(); // Call method on interface.
    }
}

Output

Read

Collections: circles in square

Collections. This program defines an interface and two classes that implement it. In Main, we create a Dictionary. We fill it with values based on the IValue interface.

Then:We use string keys to look up values in the collection. The execution engine invokes the type-based implementation.

Important:No if-statements or switch-statements are required to select the best method implementation.

Program that uses interface implementations: C#

using System;
using System.Collections.Generic;

interface IValue
{
    void Render();
}

class Content : IValue
{
    public void Render()
    {
	Console.WriteLine("Render content");
    }
}

class Image : IValue
{
    public void Render()
    {
	Console.WriteLine("Render image");
    }
}

class Program
{
    static void Main()
    {
	// Add three objects that implement the interface.
	var dictionary = new Dictionary<string, IValue>();
	dictionary.Add("cat1.png", new Image());
	dictionary.Add("image1.png", new Image());
	dictionary.Add("home.html", new Content());

	// Lookup interface objects and call implementations.
	IValue value;
	if (dictionary.TryGetValue("cat1.png", out value))
	{
	    value.Render(); // Image.Render
	}
	if (dictionary.TryGetValue("home.html", out value))
	{
	    value.Render(); // Content.Render
	}
    }
}

Output

Render image
Render content

Names. Interface types are usually named with a first letter of I. There is no language-based constraint on this. Instead, this is a convention.

And:As usual with a convention, some experts love it and others do not. We usually follow project guidelines.

Tip:The book .NET Framework Design Guidelines has many detailed recommendations about naming conventions.

Framework Design Guidelines
Check

Correctness. In Code Complete, we learn how a program's execution can be modeled on data in memory. Some techniques use type codes or enums. Object-orientation uses the type of the object.

Code Complete

And:This helps the compiler check correctness. Interfaces encode behavior in data while retaining the compiler's useful checks.


Collection abstraction: squares

Complexity. Much of the complexity in software is due to non-essential difficulties such as the bugs left behind by other programmers. But a program sometimes has essential complexity.

Essential complexity:Complexity in software that occurs because of the original problem's complexity.

Accidental complexity:This is complexity in software that occurs because of poor design choices.


Property

Property. The syntax for a property type on an interface declaration is different. The interface declarations do not include modifiers such as "public."

But:The classes that implement the properties must include those modifiers. This makes the interfaces easier to read.

Tip:Recall that interface accesses may perform a virtual method dispatch. This means the method calls are somewhat more expensive.

PropertyIndexer
Program that uses properties, interface: C#

using System;

interface IValue
{
    int Count { get; set; } // Property interface
    string Name { get; set; } // Property interface
}

class Image : IValue // Implements interface
{
    public int Count // Property implementation
    {
	get;
	set;
    }

    string _name;

    public string Name // Property implementation
    {
	get { return this._name; }
	set { this._name = value; }
    }
}

class Article : IValue // Implements interface
{
    public int Count // Property implementation
    {
	get;
	set;
    }

    string _name;

    public string Name // Property implementation
    {
	get { return this._name; }
	set { this._name = value.ToUpper(); }
    }
}

class Program
{
    static void Main()
    {
	IValue value1 = new Image();
	IValue value2 = new Article();

	value1.Count++; // Access int property on interface
	value2.Count++; // Increment

	value1.Name = "Mona Lisa"; // Use setter on interface
	value2.Name = "Resignation"; // Set

	Console.WriteLine(value1.Name); // Use getter on interface
	Console.WriteLine(value2.Name); // Get
    }
}

Output

Mona Lisa
RESIGNATION

Int

IEnumerable. This built-in interface is especially important. We can treat all arrays and Lists (and other collections) as IEnumerable types—the .NET Framework is designed this way.

So:We can use one method here (Display) to handle arguments of both array and List types. The element type (int) is fixed.

Program that uses IEnumerable: C#

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
	int[] values = { 1, 2, 3 };
	List<int> values2 = new List<int>() { 1, 2, 3 };

	// Pass to a method that receives IEnumerable.
	Display(values);
	Display(values2);
    }

    static void Display(IEnumerable<int> values)
    {
	foreach (int value in values)
	{
	    Console.WriteLine(value);
	}
    }
}

Output

1
2
3
1
2
3

Net

Built-in. In your programs, most of the interfaces you use will be built into the .NET Framework itself. The Framework is implemented with extensive interface use.

IEnumerable:The IEnumerable interface is used with many collections and also with LINQ.

IEnumerableIEnumerable, Array

IList:The IList interface is a generic interface that is implemented by arrays and the List type.

IList

IDictionary:The IDictionary interface describes a lookup or dictionary collection. It has lookup methods, including TryGetValue.

IDictionary

IComparable:The IComparable interface describes how a type is sorted against other instances of the same type.

IComparable
Base keyword

Base set. We use the mathematical concept of transitive closure. This tells us what set of interfaces form the base interfaces. This helps us figure out type hierarchies.


Concept

A base set includes "the explicit base interfaces and their base interfaces." An interface has the base interface of its immediate ancestor—and all of its further ancestors (13.1.3).

So:Interfaces in the C# language can be described, mathematically, with the concept of transitive closure.


Virtual keyword

Performance. In many benchmarks, a simple switch statement performs slightly better than a virtual method. But with later changes, the switch statement may grow in size and reduce speed.


Also, avoiding object-oriented design may increase complexity over a project's lifecycle. It may require more debugging code. This will reduce performance.

Tip:The effects of these changes are sometimes unexpected. Many considerations factor into performance.

Sealed
Question and answer

Question. Suppose you have the option to use interfaces or virtual methods. Which version is faster? I benchmark interfaces against virtual methods.

Interface Performance
Size

Effect size. The performance loss with the interface method is tiny, often less than a nanosecond. First make sure the big picture is correct. Then think about optimizations.


Not equal

When I learned C# I wondered about the difference between abstract classes and interfaces. This was a topic of concern.
But now,
years later,
I have changed perspective.


Object-oriented programming

Abstract classes, unlike interfaces, can have fields. This is good to know. But what we need to focus on is higher-level details of program design, not technical issues.


Reading

Research. The more you read, the more you know. This is true unless you read the same book over and over again. If you do that, I probably cannot help you.

An interface defines a contract. Hejlsberg et al., p. 561

Prefix interface names with the letter I, to indicate that the type is an interface. Abrams & Cwalina, p. 56


A tiny review. An interface is less concrete, more abstract. During execution, the runtime selects an implementation.
With a language feature,
the type system,
we encode behavior as data.

C#