Члены типа интерфейса всегда открыты. Для этого необходимо, чтобы их реализация была общедоступной. Это не составляет, например:
interface IFoo { void Bar(); }
class Baz : IFoo {
private void Bar() { } // CS0737
}
Явная реализация интерфейса обеспечивает синтаксис, который позволяет метод быть частным:
class Baz : IFoo {
void IFoo.Bar() { } // No error
}
Классическим использовать для этого, чтобы скрыть реализацию базового интерфейса тип. IEnumerable <> будет очень хороший пример:
class Baz : IEnumerable<Foo> {
public IEnumerator<Foo> GetEnumerator() {}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { }
}
Обратите внимание, как общая версия доступна, то необщая версия скрыта. Это и препятствует его использованию, и позволяет избежать ошибки компиляции из-за дублирования метода.
В вашем случае неправильная реализация утилиты() явно неверна. Вы написали Dispose(), чтобы клиентский код вызывал его, заставляя его отличать от IDisposable, чтобы сделать вызов, не имеет смысла.
Кроме того, вызов Dispose() из финализатора является запахом кода. Стандартный шаблон заключается в добавлении защищенного метода Dispose (bool disposing) в ваш класс.