Почему я не получаю предупреждение компилятора при реализации интерфейса, который также реализует базовый класс? - PullRequest
4 голосов
/ 21 сентября 2010

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

Почему компилятор C # не предупредит об этом? Это кажется опасным по нескольким причинам. Я мог бы реализовать интерфейс, реализованный базой, который дал бы мне поведение, которого я не ожидал (например, база больше не располагала). Или, если позже я решу, чтобы база реализовала новый интерфейс, я должен отсканировать весь мой код, чтобы найти любые производные, которые уже могут его реализовывать.

Для дублированных членов в производных классах компилятор требует, чтобы мы использовали 'override' или 'new'.

Почему интерфейсы разные?

class CA : IDisposable
{
    void IDisposable.Dispose() { Debug.WriteLine("CA.Dispose"); }
}

class CB : CA, IDisposable
{
    void IDisposable.Dispose() { Debug.WriteLine("CB.Dispose"); }
}

class Program
{
    static void Main(string[] args)
    {
        using (new CB()) { }
    }
}

// output: CB.Dispose

1 Ответ

6 голосов
/ 21 сентября 2010

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

using System;
using System.Diagnostics;

class CA : IDisposable
{
    public void Dispose()
    {
        Debug.WriteLine("CA.Dispose");
    }
}

class CB : CA, IDisposable
{
    public void Dispose()
    {
        Debug.WriteLine("CB.Dispose");
    }
}

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

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

Если честно, если на позднем этапе вы решите, что базовый класс должен начать реализацию IDisposable, вы все равно окажетесь в мире боли - потому что вам придется проверять каждое место, где вы его используете класс, чтобы определить, нужен ли вам оператор using.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...