Почему метод класса С#, реализованный в классе, должен быть общедоступным?

У меня есть класс, который наследует интерфейс. Метод члена интерфейса реализован в моем классе без модификатора доступа (поэтому он по умолчанию является закрытым).

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

Почему это запрещено? Не могу ли я переопределить доступность?

Ответ 1

Вот пример того, почему нет смысла переопределять видимость:

interface someI
{
    void doYourWork();
}
public class A : someI
{
    public void doYourWork()
    {
        //...
    }
}

public class B : someI
{
    private void doYourWork()
    {
        //...
    }
}
void Main()
{
    List<someI> workers = getWorkers();
    foreach(var worker in workers)
        worker.doYourWork();
}

Что происходит, когда ваш рабочий имеет тип B? Вы вызываете метод, как если бы он был общедоступным, но это частный метод. Если вы хотите эту функциональность, то это не частный метод?

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

public class B : someI
{
    void someI.doYourWork()
    {
        //...
    }
}

И вы закончите с этим:

var b = new B();
b.doYourWork(); // Not accessible
((someI)b).doYourWork(); // Accessible

Ответ 2

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

У вас есть несколько вариантов здесь, чтобы "изменить" видимость этого метода. Дано:

public interface IFoo 
{
    bool IsFoo();
}

а. Внедрите метод явно

public class Foo : IFoo
{
    bool IFoo.IsFoo() { return true; }
}

Этот метод будет доступен только через интерфейс (IFoo в этом случае.)

В. Изменение видимости интерфейса

Определите интерфейс как internal вместо public. Как следствие, однако, Foo также должен быть internal.

Ответ 3

Требование, чтобы реализация интерфейса была общедоступной, является просто логическим требованием. Когда вы реализуете интерфейс, вы говорите компилятору "Эй, я реализую каждый метод на этом интерфейсе". Таким образом, использование метода private делает его более недоступным - и логически не реализовано. Интерфейсы служат контрактом для кода, который использует ваш объект, говоря, что вы всегда можете вызывать любой метод, определенный в интерфейсе на моем объекте. Если метод реализации был закрытым, это будет больше недействительным.

Если вы хотите скрыть свою реализацию, скажем, Intellisense, тогда вы можете просто реализовать метод явно, как упоминает @Bryan.