C#: явное указание интерфейса в методе реализации

Почему при реализации интерфейса, если я делаю метод публичным, мне не нужно явно указывать интерфейс, но если я делаю его приватным, я должен... вот так (GetQueryString это метод из IBar< /эм>):

public class Foo : IBar
{
    //This doesn't compile
    string GetQueryString() 
    {
        ///...
    }

    //But this does:
    string IBar.GetQueryString() 
    {
        ///...
    }
}

Так почему же вы должны явно указывать интерфейс, когда метод делается закрытым, но не когда метод общедоступный?


person Andreas Grech    schedule 17.06.2009    source источник
comment
Когда вы говорите, что не работает, вы имеете в виду - не компилируется или работает не так, как ожидалось?   -  person Simeon Pilgrim    schedule 17.06.2009


Ответы (1)


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

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

public class Foo : IBar
{
    // Implicit implementation
    public string GetQueryString() 
    {
        ///...
    }

    // Explicit implementation - no access modifier is allowed
    string IBar.GetQueryString() 
    {
        ///...
    }
}

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

public class Foo : IEnumerable<string>
{
    public IEnumerator<string> GetEnumerator()
    {
        ...
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator(); // Call to the generic version
    }
}

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

person Jon Skeet    schedule 17.06.2009
comment
Джон, я внес поправки в свой код в посте, потому что я допустил ошибку ранее, наметив именно свой код. - person Andreas Grech; 17.06.2009