Хотя вы можете сделать сам интерфейс внутренним, методы все равно будут частью общедоступного API. Вы можете выбрать явную реализацию интерфейса, так что API, определенный интерфейсом, виден только через интерфейс, а не через класс.
interface IFoo
{
void M();
}
interface IBar
{
void X();
}
public class Bar : IBar, IFoo
{
public void X() // part of the public API of Bar
{
}
void IFoo.M() // explicit implementation, only visible via IFoo
{
}
}
Bar bar = new Bar();
bar.X(); // visible
bar.M(); // NOT visible, cannot be invoked
IFoo foo = bar;
foo.M(); // visible, can be invoked
Помимо этого, если вам нужен мир, чтобы никогда не представлял, что класс поддерживает интерфейс, то вам просто не нужно, чтобы класс реализовывал интерфейс. Интерфейсы предназначены для трансляции того, что данный объект поддерживает заданное поведение, явно или иначе. Если это не то, что вы хотите, вам нужно пойти в другом направлении. Может случиться так, что класс реализует поведение как частные детали реализации, без интерфейса. Другой подход состоит в том, чтобы поместить эти реализации в закрытый вложенный класс.
public class Bar : IBar
{
Foo foo = new Foo();
public void X() { }
public void DoSomething()
{
this.foo.M(); // invokes method of instance of nested class
}
class Foo : IFoo
{
public void M() { }
}
}
При таком подходе мир никогда не знает, что класс выполняет контракт интерфейса, , потому что технически это не делает. Контракт выполняется Foo
, и мир не может видеть Foo
. Однако преимущество заключается в том, что если классу необходимо вызывать внешние методы, которые требуют интерфейса, он все равно может передать вложенный экземпляр класса этим методам.