24

I have two options in VS2010 for implementing interfaces.

enter image description here

When I have IHelper.cs interface as follows:

public interface IHelper
    ....
    IEnumerable<IPort> Ports { get; }

"Implement Interface Explicitly" gives this code:

    IEnumerable<IPort> IHelper.Ports
    {
        get
        {
            ...
        }
    }

And, "Implement Interface" gives me this code:

    public IEnumerable<IPort> Ports
    {
        get
        {
            ...
        }
    }

Are they the same or different? Why do I have two options in implementing interfaces in C#?

prosseek
  • 182,215
  • 215
  • 566
  • 871
  • 1
    Would "Implement Public Interface" and "Implement Private Interface" have been too difficult? – PRMan May 06 '16 at 19:47

3 Answers3

38

Explicit interface declarations mean that the interface members are not available on types other than the interface itself, so implementing types would need to be cast to the interface before accessing them publicly.

Implicit, the standard way in which most interfaces are implemented, exposes interface items on the implementor-type's public API.

The main reason for explicit interface definitions is to avoid naming conflicts if you happen to implement two interfaces that contain methods with the same signature... the explicit definition allows the compiler to keep the signatures distinct enough to resolve.

A secondary reason that supports code maintenance, as suggested by XenoPuTtSs in the comments, is that explicit definitions will trigger compiler errors on the implementing types if the method signature is removed. On implicit implementations, removing a method from the interface will leave the method as a regular member of any types - meaning you need to search manually for now-defunct method implementations.

Adam Houldsworth
  • 63,413
  • 11
  • 150
  • 187
  • 5
    also (which is not a main reason) when the interface changes (like a method is removed or changes) the compiler will throw an error on classes that are Explicitly defining interfaces because those methods are no longer on the interface. This is a helpful way (IMHO) for locating unused code from large projects. – XenoPuTtSs Jun 19 '12 at 20:19
  • @XenoPuTtSs Good point, I've amended my answer to include this. – Adam Houldsworth Jun 19 '12 at 20:24
  • 1
    Another reason: keeping default values for optional parameters. – marsze Jun 29 '22 at 14:51
9

They are totally different. If you implement interfaces explicitely you'll be able to reference the interface members only by reference of that interface. The following code demonstrates the idea.

public interface IFoo {
    String Bar { get; set; }
}
public class ImplicitFoo : IFoo {
    public string Bar {get;set;}
}
public class ExplicitFoo : IFoo {
    private String _Bar;
    string IFoo.Bar {
        get {
            return _Bar;
        }
        set {
            _Bar = value;
        }
    }
}
public class Test {
    public void Test() {
        var iml = new ImplicitFoo();
        // Works fine
        Console.WriteLine(iml.Bar);
        var expl = new ExplicitFoo();
        var fooInterface = (IFoo)expl;
        // Works fine
        Console.WriteLine(fooInterface.Bar);
        // Throws compile time exception
        Console.WriteLine(expl.Bar);
    }
}
Oybek
  • 7,016
  • 5
  • 29
  • 49
8

A class that implements an interface can explicitly implement a member of that interface. When a member is explicitly implemented, it cannot be accessed through a class instance, but only through an instance of the interface.

// explicit1.cs
interface IDimensions 
{
  float Length();
  float Width();
}

class Box : IDimensions 
{
  float lengthInches;
  float widthInches;

 public Box(float length, float width) 
 {
    lengthInches = length;
   widthInches = width;
 }
 // Explicit interface member implementation: 
 float IDimensions.Length() 
 {
    return lengthInches;
 }
 // Explicit interface member implementation:
 float IDimensions.Width() 
 {
    return widthInches;      
 }

 public static void Main() 
 {
   // Declare a class instance "myBox":
   Box myBox = new Box(30.0f, 20.0f);
  // Declare an interface instance "myDimensions":
  IDimensions myDimensions = (IDimensions) myBox;
  // Print out the dimensions of the box:
  /* The following commented lines would produce compilation 
     errors because they try to access an explicitly implemented
     interface member from a class instance:                   */
  //System.Console.WriteLine("Length: {0}", myBox.Length());
  //System.Console.WriteLine("Width: {0}", myBox.Width());
  /* Print out the dimensions of the box by calling the methods 
     from an instance of the interface:                         */
  System.Console.WriteLine("Length: {0}", myDimensions.Length());
  System.Console.WriteLine("Width: {0}", myDimensions.Width());
 }
}

Explicit interface implementation also allows the programmer to inherit two interfaces that share the same member names and give each interface member a separate implementation. This example displays the dimensions of a box in both metric and English units. The Box class inherits two interfaces IEnglishDimensions and IMetricDimensions, which represent the different measurement systems. Both interfaces have identical member names, Length and Width.

look at the example

// explicit2.cs
// Declare the English units interface:
interface IEnglishDimensions 
{
  float Length();
  float Width();
}
// Declare the metric units interface:
interface IMetricDimensions 
{
   float Length();
   float Width();
}
// Declare the "Box" class that implements the two interfaces:
// IEnglishDimensions and IMetricDimensions:
class Box : IEnglishDimensions, IMetricDimensions 
{
   float lengthInches;
   float widthInches;
 public Box(float length, float width) 
  {
    lengthInches = length;
    widthInches = width;
  }
// Explicitly implement the members of IEnglishDimensions:
float IEnglishDimensions.Length() 
{
  return lengthInches;
}
float IEnglishDimensions.Width() 
{
  return widthInches;      
}
 // Explicitly implement the members of IMetricDimensions:
float IMetricDimensions.Length() 
{
   return lengthInches * 2.54f;
}
float IMetricDimensions.Width() 
{
  return widthInches * 2.54f;
}
public static void Main() 
{
  // Declare a class instance "myBox":
  Box myBox = new Box(30.0f, 20.0f);
  // Declare an instance of the English units interface:
  IEnglishDimensions eDimensions = (IEnglishDimensions) myBox;
  // Declare an instance of the metric units interface:
  IMetricDimensions mDimensions = (IMetricDimensions) myBox;
  // Print dimensions in English units:
  System.Console.WriteLine("Length(in): {0}", eDimensions.Length());
  System.Console.WriteLine("Width (in): {0}", eDimensions.Width());
  // Print dimensions in metric units:
  System.Console.WriteLine("Length(cm): {0}", mDimensions.Length());
  System.Console.WriteLine("Width (cm): {0}", mDimensions.Width());
 }
}

for more details look at this article

Sergey K
  • 4,071
  • 2
  • 23
  • 34
  • 1
    It's best to include the relevant pieces of information from the article in the answer itself, links are fickle and may not live as long as the answer. Were that link to fail, your answer would provide no help. – Adam Houldsworth Feb 08 '12 at 14:55