Внедрить интерфейс или реализовать интерфейс Явно в С#

У меня есть два варианта в VS2010 для реализации интерфейсов.

enter image description here

Когда у меня есть интерфейс IHelper.cs следующим образом:

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

"Осуществить интерфейс Явно" дает этот код:

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

И, "реализовать интерфейс" дает мне этот код:

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

Являются ли они одинаковыми или разными? Почему у меня есть два варианта реализации интерфейсов в С#?

Ответы

Ответ 1

Явные декларации интерфейса означают, что члены интерфейса недоступны для типов, отличных от самого интерфейса, поэтому реализации типов необходимо будет отнести к интерфейсу, прежде чем публиковать их.

Неявный стандартный способ реализации большинства интерфейсов предоставляет элементы интерфейса в общедоступном API-интерфейсе разработчика.

Основная причина для явных определений интерфейсов заключается в том, чтобы избежать конфликтов имен, если вы реализуете два интерфейса, которые содержат методы с одной и той же сигнатурой... явное определение позволяет компилятору различать сигнатуры достаточно, чтобы разрешить.

Вторая причина, которая поддерживает поддержку кода, как предложено XenoPuTtS в комментариях, заключается в том, что явные определения будут вызывать ошибки компилятора для типов реализации, если подпись метода удалена. При неявных реализациях удаление метода из интерфейса оставит этот метод в качестве регулярного члена любого типа - это означает, что вам нужно искать вручную в настоящее время недействительные реализации методов.

Ответ 2

Они совершенно разные. Если вы реализуете интерфейсы явно, вы сможете ссылаться на члены интерфейса только по ссылке этого интерфейса. Следующий код демонстрирует идею.

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);
    }
}

Ответ 3

Класс, реализующий интерфейс, может явно реализовать элемент этого интерфейса. Когда элемент явно реализован, к нему нельзя получить доступ через экземпляр класса, но только через экземпляр интерфейса.

// 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());
 }
}

Явная реализация интерфейса также позволяет программисту наследовать два интерфейса, которые имеют одни и те же имена элементов и дают каждому члену интерфейса отдельную реализацию. В этом примере отображаются размеры окна как в метрических, так и в английских единицах. Класс Box наследует два интерфейса IEnglishDimensions и IMetricDimensions, которые представляют собой различные измерительные системы. Оба интерфейса имеют одинаковые имена элементов, Length и Width.

посмотрите пример

// 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());
 }
}

для более подробной информации смотрите статья