"By using the interface, I allow myself the advantage of making it easier to change implementations later on if I need to. Another implementation may provide performance improvements, some database interaction features, or other benefits. By programming to the interface rather than to the implementation, I avoid having to change all the code should I need a different implementation... You should always try to program to an interface like this; always use the most general type you can." - Martin Fowler - UML Distilled: A Brief Guide to the Standard Object Modeling Language, Third Edition by Martin Fowler
Let's take a look at the following code as an example:
1 [Test]
2 public void GetStudents_ShouldReturnAllStudents( )
3 {
4 List< Student > students = _store.GetStudents( );
5 Assert.IsNotNull( students );
6 foreach ( Student student in students )
7 {
8 Console.WriteLine( student.FirstName + student.LastName );
9 }
10 }
The code above is tightly bound to a specialized type of collection, List
![]()
If we wanted to code to an abstraction, in this case we have two options, IList
If we take a look at IList
![]()
As you can see IList
![]()
The final code looks more like this:
1 [Test]
2 public void GetStudents_ShouldReturnAllStudents( )
3 {
4 ICollection< Student > students = _store.GetStudents( );
5 Assert.IsNotNull( students );
6 foreach( Student student in students )
7 {
8 Console.WriteLine( student.FirstName + student.LastName );
9 }
10 }
As a side note, for this particular contrived example since ICollection
1 [Test]
2 public void GetStudents_ShouldReturnAllStudents( )
3 {
4 IEnumerable < Student > students = _store.GetStudents( );
5 Assert.IsNotNull( students );
6 foreach( Student student in students )
7 {
8 Console.WriteLine( student.FirstName + student.LastName );
9 }
10 }
Additional Resources: * C# Interface Based Development * The Interface Construct in C#