[c#] 인터페이스를 명시 적으로 구현하는 이유는 무엇입니까?

그렇다면 인터페이스를 명시 적으로 구현하는 좋은 사용 사례는 정확히 무엇일까요?

클래스를 사용하는 사람들이 intellisense에서 이러한 모든 메서드 / 속성을 볼 필요가 없도록하는 것입니까?



답변

동일한 메서드와 다른 구현으로 두 개의 인터페이스를 구현하는 경우 명시 적으로 구현해야합니다.

public interface IDoItFast
{
    void Go();
}
public interface IDoItSlow
{
    void Go();
}
public class JustDoIt : IDoItFast, IDoItSlow
{
    void IDoItFast.Go()
    {
    }

    void IDoItSlow.Go()
    {
    }
}


답변

선호하지 않는 회원을 숨기는 것이 유용합니다. 예를 들어 두 가지를 모두 구현 IComparable<T>하고 IComparable일반적 IComparable으로 다른 유형의 개체를 비교할 수 있다는 인상을주지 않도록 오버로드를 숨기는 것이 더 좋습니다. 마찬가지로 일부 인터페이스는과 같이 CLS 규격이 아니므로 인터페이스를 IConvertible명시 적으로 구현하지 않으면 CLS 규격이 필요한 언어의 최종 사용자가 개체를 사용할 수 없습니다. (BCL 구현자가 기본 요소의 IConvertible 멤버를 숨기지 않으면 매우 비참 할 것입니다. :))

또 다른 흥미로운 점은 일반적으로 그러한 구조를 사용한다는 것은 인터페이스를 명시 적으로 구현하는 구조체가 인터페이스 유형에 대한 boxing을 통해서만 호출 할 수 있다는 것을 의미합니다. 일반 제약 조건을 사용하여이 문제를 해결할 수 있습니다.

void SomeMethod<T>(T obj) where T:IConvertible

당신이 그것을 전달할 때 int를 boxing하지 않습니다.


답변

인터페이스를 명시 적으로 구현해야하는 몇 가지 추가 이유 :

이전 버전과의 호환성 : ICloneable인터페이스가 변경되는 경우 구현하는 메서드 클래스 멤버는 메서드 서명을 변경할 필요가 없습니다.

클리너 코드 : CloneICloneable에서 메서드가 제거 되면 컴파일러 오류가 발생 하지만 메서드를 암시 적으로 구현하면 사용하지 않는 ‘고아’공용 메서드로 끝날 수 있습니다.

강력한 타이핑 : 예제를 통해 supercat의 이야기를 설명하기 위해 이것이 제가 선호하는 샘플 코드입니다. ICloneable명시 적으로 구현 Clone()하면 MyObject인스턴스 멤버 로 직접 호출 할 때 강력한 타이핑이 허용 됩니다 .

public class MyObject : ICloneable
{
  public MyObject Clone()
  {
    // my cloning logic;  
  }

  object ICloneable.Clone()
  {
    return this.Clone();
  }
}


답변

또 다른 유용한 기술은 함수의 공용 메서드 구현이 인터페이스에 지정된 것보다 더 구체적인 값을 반환하도록하는 것입니다.

예를 들어 객체는을 구현할 수 ICloneable있지만 공개적으로 표시되는 Clone메서드가 자체 유형을 반환하도록합니다.

마찬가지로,는 IAutomobileFactory있을 수 있습니다 Manufacture을 반환하는 방법을 Automobile하지만 FordExplorerFactory, 어떤 구현 IAutomobileFactory, 그것있을 수 있습니다 Manufacture방법은 반환 FordExplorer(에서 어떤 도출을 Automobile). 타입 캐스트 할 필요없이 a에 의해 반환 된 객체에 대한 특정 속성을 FordExplorerFactory사용할 수 있음을 알고 있는 코드는 단지 어떤 유형이 있다는 것을 알고있는 코드 는 단순히 .FordExplorerFordExplorerFactoryIAutomobileFactoryAutomobile


답변

멤버 이름과 서명이 동일한 두 개의 인터페이스가 있지만 사용 방법에 따라 동작을 변경하려는 경우에도 유용합니다. (나는 이와 같은 코드를 작성하지 않는 것이 좋습니다) :

interface Cat
{
    string Name {get;}
}

interface Dog
{
    string Name{get;}
}

public class Animal : Cat, Dog
{
    string Cat.Name
    {
        get
        {
            return "Cat";
        }
    }

    string Dog.Name
    {
        get
        {
            return "Dog";
        }
    }
}
static void Main(string[] args)
{
    Animal animal = new Animal();
    Cat cat = animal; //Note the use of the same instance of Animal. All we are doing is picking which interface implementation we want to use.
    Dog dog = animal;
    Console.WriteLine(cat.Name); //Prints Cat
    Console.WriteLine(dog.Name); //Prints Dog
}


답변

인터페이스를 명시 적으로 구현하기 위해 공용 인터페이스를 깔끔하게 유지할 수 있습니다. 즉, File클래스가 IDisposable명시 적으로 구현 하고 ) Close()보다 소비자에게 더 의미가 있는 공용 메서드 를 제공 할 수 있습니다 Dispose(.

F # 은 명시 적 인터페이스 구현 제공하므로 해당 기능에 액세스하려면 항상 특정 인터페이스로 캐스팅해야하므로 인터페이스를 매우 명시 적으로 (말장난없이) 사용할 수 있습니다.


답변

내부 인터페이스가 있고 클래스에서 멤버를 공개적으로 구현하지 않으려면 명시 적으로 구현합니다. 암시 적 구현은 공개되어야합니다.