C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
Main: 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.
C# program that uses interface
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
C# program that converts class to interface
using System;
interface ITest
{
void Message();
}
class Test : ITest
{
public void Message()
{
Console.WriteLine("MESSAGE");
}
}
class Program
{
static void Main()
{
// Create Test object.
Test test = new Test();
test.Message();
// Convert the class to its interface.
ITest perl = test as ITest;
if (perl != null)
{
perl.Message();
}
}
}
Output
MESSAGE
MESSAGE
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.
C# program that uses interface implementations
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());
// Look up 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
Part 1: We create instances of the Image and Article classes, and reference them through the IValue interface.
Part 2: We access the properties from the IValue interface, which are implemented by Image and Article.
C# program that uses properties, interface
using System;
interface IValue
{
int Count { get; set; }
string Name { get; set; }
}
class Image : IValue
{
public int Count
{
get;
set;
}
string _name;
public string Name
{
get { return this._name; }
set { this._name = value; }
}
}
class Article : IValue
{
public int Count
{
get;
set;
}
string _name;
public string Name
{
get { return this._name; }
set { this._name = value.ToUpper(); }
}
}
class Program
{
static void Main()
{
// Part 1: create class instances, and use interface variables.
IValue value1 = new Image();
IValue value2 = new Article();
// Part 2: access properties on interfaces.
value1.Count++;
value2.Count++;
value1.Name = "Mona Lisa";
value2.Name = "Resignation";
Console.WriteLine(value1.Name);
Console.WriteLine(value2.Name);
}
}
Output
Mona Lisa
RESIGNATION
So: We can use one method here (Display) to handle arguments of both array and List types. The element type (int) is fixed.
C# program that uses IEnumerable
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
Version 1: The code declares a type that implements a method from an interface. It calls a method through an interface.
Version 2: The program declares a type that implements a method matching a base class virtual method. It uses a virtual method.
Result: The virtual call is faster. Changing interfaces to base classes with virtual methods can speed up method invocations.
However: The performance loss with the interface method is tiny. The big picture is more important.
C# program that tests performance
using System;
using System.Diagnostics;
interface IInterfaceExample
{
void Y();
}
class ImplementsInterface : IInterfaceExample
{
public void Y()
{
}
}
class BaseExample
{
public virtual void Y()
{
}
}
class DerivesBase : BaseExample
{
public override void Y()
{
}
}
class Program
{
const int _max = 100000000;
static void Main()
{
IInterfaceExample interface1 = new ImplementsInterface();
BaseExample base1 = new DerivesBase();
interface1.Y();
base1.Y();
// Version 1: call interface method.
var s1 = Stopwatch.StartNew();
for (int i = 0; i < _max; i++)
{
interface1.Y();
}
s1.Stop();
// Version 2: call virtual method.
var s2 = Stopwatch.StartNew();
for (int i = 0; i < _max; i++)
{
base1.Y();
}
s2.Stop();
Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000 * 1000) /
_max).ToString("0.00 ns"));
Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000 * 1000) /
_max).ToString("0.00 ns"));
Console.Read();
}
}
Output
3.21 ns Interface method call
2.24 ns Virtual method call
Tip: The effects of these changes are sometimes unexpected. Many considerations factor into performance.
IEnumerable: The IEnumerable interface allows foreach-loops on collections. It is often used in LINQ.
IEnumerableIList: The IList interface is a generic interface that is implemented by arrays and the List type.
IListIDictionary: The IDictionary interface describes a lookup or dictionary collection. It has lookup methods, including TryGetValue.
IDictionaryIComparable: The IComparable interface describes how a type is sorted against other instances of the same type.
IComparableThen: From the drop-down menu, select "Implement interface." Then remove the NotImplementedExceptions and write the C# method bodies.
So: Interfaces in the C# language can be described, mathematically, with the concept of transitive closure.
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.
Quote: An interface defines a contract (The C# Programming Language).
Quote: Prefix interface names with the letter I, to indicate that the type is an interface (Framework Design Guidelines).
And: This helps the compiler check correctness. Interfaces encode behavior in data—and retain the compiler's useful checks.