What are some advantages to using an interface in C#?

20,366

Solution 1

An interface says how something should work. Think of it as a contract or a template. It is key to things such as Inverson of Control or Dependancy Injection.

I use Structure Map as my IoC container. This allows me to define an interface for all of my classes. Where you might say

Widget w = new Widget();

I would say

IWidget w = ObjectFactory.GetInstance<IWidget>();

This is very powerful in that my code isn't saying necessarily what a Widget truely is. It just knows what a Widget can do based on the interface of IWidget.

This has some great power to it in that now that I am using an IoC container I can do a couple more nifty things. In my unit tests where I need to use a Widget I can create a mock for Widget. So say that my Widget does something very powerful by way of connecting to a database or a web service, my mock can simulate connecting to these resources and return to me stubbed data. This makes my test run faster and behave in a way that is more reliable. Because I am using StructureMap I can tell StructureMap to load the real implementation of my Widget during production use of my code and the mocked version of the Widget during testing either programatically or by configuration.

Also, because I am using an IoC container I can provide cool new features to my application such as writing three different ways to cache data. I can have a local developer box cache using a tool such as Lucene.NET for a local cache. I can have a development server use the .NET cache which runs great on one box. And then I can have a third option for my production servers use a cache layer such as MemCache Win32 or Velocity. As long as all three caching implementations conform to the same interface, their actual implementation doesn't concern me (or my code) at all. I simply ask StructureMap to go get the current environments implementation and then go to work.

If you follow Dependency Injection at all then interfaces come in handy here also with an IoC container such as StructureMap in that I can declare the usage of a class by way of an Interface in the constructor of my class.

public class Widget(IWidgetRepository repository, IWidgetService service) : IWidget
{
    //do something here using my repository and service
}

And then when I new up an instance of Widget by way of StructureMap such as this

IWidget widget = ObjectFactory.GetInstance<IWidget>();

Notice that I am not specifying the repository or service in the constructor. StructureMap knows by way of the interfaces specified in the constructor how to go get the appropriate instances and pass them in too. This makes very powerful and clean code!

All from the simple definition of Interfaces and some clever usage of them!

Solution 2

The basic case is the "IWriter" case.

Suppose you are making a class that can write to the console, and it has all kinds of useful functions like write() and peek().

Then you would like to write a class that can write to the printer, so instead of reinventing a new class, you use the IWriter interface.

Now the cool thing about interfaces is you can write all your writing code, without knowing what is your writing target beforehand, and then can when the user decides (at runtime) weather he wants to write to the console or the printer, you just define the object as a console/printer writer and you don't need to change anything in your writing code, because they both use the same front end (interface).

Solution 3

One Simple Answer: Use interfaces to program against the contract rather than the implementation.

How could that possibly help? Starting to use interfaces will (hopefully) get you in the habit of coupling classes more loosely. When you code against your own concrete classes, it's easy to start poking the data structures without a strict separation of concerns. You end up with classes which "know" everything about the other classes and things can get pretty tangled. By limiting yourself to an interface, you only have the assurance that it fulfills the interface's contract. It injects a sometimes helpful friction against tight coupling.

Solution 4

An example. Consider an MDI application that shows reports, there's basically 2 different report types. A chart, and a grid. I need to Save these reports as PDF and I need to mail them to someone. The event handler for the menu the user clicks to save a report to PDF could do this:

void ExportPDF_Clicked(...) {
   if(currentDocument is ChartReport) {
      ChartReport r = currentDocument as ChartReport;
      r.SavePDF();
   } else if(currentDocument is GridReport) {
     GridReport r = currentDocument as GridReport;
      r.SavePDF();
   }
}

I'll rather make my ChartReport and GridReport implement this interface:

public interface Report {
  void MailTo();
  void SavePDF();
}

Now I can do:

void ExportPDF_Clicked(...) {
   Report r = currentDocument as Report;
   r.SavePDF();
}

Similar for other code that need to do the same operation(save it to a file,zoom in,print,etc.) on the different report types. The above code will still work fine when I add a PivotTableReport also impelmenting Rpoert the next week.

Solution 5

IOC and Dependency injection have already been mentioned above, and I would urge you to look at them.

Largely, however, interfaces allow a contract to be specified for an object that doesn't require an inheritance model.

Lets say I have class Foo, that has functions x and y and property z, and I build my code around it.

If I discover a better way to do Foo, or another sort of Foo requires implementation, I can, of course, extend a base Foo class to FooA, FooB, MyFoo etc, however that would require that all Foos have the same core functionality, or, indeed that any future Foo creators have access to the base Foo class and understand its internal workings. In C#, that would mean future Foos could not inherit from anything else but Foo, as C# does not support multiple inheritance.

It would also require me to be aware of possible future states of Foo, and try not to inhibit them in my base Foo class.

Using an interface IFoo simply states the 'contract' that a class requires to work in my Foo framework, and I don't care what any future Foo classes may inherit from or look like internally, as long as they have fn x fn y and z. It makes a framework much more flexible and open to future additions.

If, however, Foo requires a large amount of core at its base to work that would not be applicable in a contract scenario, that is when you would favour inheritance.

Share:
20,366

Related videos on Youtube

Kevin
Author by

Kevin

Updated on July 09, 2022

Comments

  • Kevin
    Kevin almost 2 years

    I was forced into a software project at work a few years ago, and was forced to learn C# quickly. My programming background is weak (Classic ASP).

    I've learned quite a bit over the years, but due to the forced nature of how I learned C#, there are a lot of basic concepts I am unclear on.

    Specifically, an interface. I understand the basics, but when writing an app, I'm having a hard time figuring out a practical use of one. Why would one want to write an interface for their application?

    Thanks Kevin