Как выбрать, следует ли реализовать интерфейс или явно реализовать интерфейс? - PullRequest
4 голосов
/ 29 декабря 2010

Существует два способа реализации интерфейса:

interface IMyInterface
{
    void Foo();
}

class IImplementAnInterface : IMyInterface
{
    public void Foo()
    {
    }
}
// var foo = new IImplementAnInterface();
// foo.Foo(); //Ok
// ((IMyInterface)foo).Foo(); //Ok

class IExplicitlyImplementAnInterface : IMyInterface
{
    void IMyInterface.Foo()
    {
    }
}
// var foo = new IExplicitlyImplementAnInterface();
// foo.Foo(); //ERROR!
// ((IMyInterface)foo).Foo(); //Ok

Разница в том, что если интерфейс реализован явно, он должен быть фактически приведен как данный интерфейс, прежде чем кому-либо разрешат вызвать FooМетод.

Как решить, какой использовать?

Ответы [ 4 ]

5 голосов
/ 29 декабря 2010

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

В противном случае вы можете выбирать. Если вы хотите скрыть некоторые реализованные методы, вы выбираете явный метод. Например, класс Dictionary <,> делает это с некоторыми методами интерфейса ICollection <>, потому что скрытые методы могут сбить людей с толку.

2 голосов
/ 29 декабря 2010

В некоторых случаях необходимо предоставить явную реализацию, например, при реализации IEnumerable и IEnumerable <>, когда оба интерфейса предоставляют метод GetEnumerator.

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

Это было трудно сказать, но я надеюсь, что это имеет смысл.

1 голос
/ 29 декабря 2010

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

Вы также можете явно реализовать метод, чтобы эффективно «скрыть» его и реализовать эквивалентный метод с лучшим именем. System.IO.Stream делает это, явно реализуя Dispose и предоставляя лучше названное Close ().

См. Эту статью MSDN для получения дополнительной информации: http://msdn.microsoft.com/en-us/library/ms229034.aspx.

0 голосов
/ 29 декабря 2010

Обычно это обходной путь для .NET, запрещающий «ковариацию возвращаемого типа».

...