Как скрыть некоторые элементы интерфейса - PullRequest
9 голосов
/ 12 марта 2011

Я хотел бы создать собственную коллекцию, которая реализует ICollection.

Но я бы не хотел показывать некоторые элементы метода ICollection, например Clear.

Как этого добиться?

Ответы [ 7 ]

19 голосов
/ 12 марта 2011

Вы можете явно реализовать интерфейс и скрыть реализацию:

public class UrClass : ICollection
{
    void ICollection.Clear() { ... }
}

Пользователь не может вызвать urClassInstance.Clear() напрямую, но он может вызвать ((ICollection)urClassInstance).Clear() косвенно, как это.

2 голосов
/ 12 марта 2011

Вы можете сделать его пустым или запустить NotImplementedException

2 голосов
/ 12 марта 2011

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

Существует два способа объявления членов, которые удовлетворяют требованиям интерфейса: неявно и явно.

Неявно, будет использоваться любой открытый член с подходящей подписью:

public interface IGuess
{
    void Guess();
}

public class Guy : IGuess
{
    public void Guess() {}
}

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

Вы также можете, как указывает @Jaroslav, явно указывать элементы как удовлетворяющие определению интерфейса:

public class Guy : IGuess
{
    void IGuess.Guess() {}
}

В этом случае элемент не появится, если экземпляр не приведен к типу интерфейса. Это все еще публично.

1 голос
/ 12 марта 2011

Возможно, вы захотите взглянуть на ReadOnlyCollection . Вы можете создать приватный внутренний класс и позволить ему реализовать ICollection. Затем создайте метод, который возвращает ReadOnlyCollection, вызвав AsReadOnly для этого объекта. Или просто создайте подкласс, если это соответствует вашему дизайну. Желательно создавать подклассы для этой коллекции, а не пытаться создать собственную реализацию.

0 голосов
/ 12 марта 2011

Я бы предпочел, чтобы вы рассмотрели "Композиция" вместо "Наследование" здесь.

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

0 голосов
/ 12 марта 2011

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

0 голосов
/ 12 марта 2011

Если вы просто хотите скрыть эти элементы от интерфейса вашей собственной коллекции, вы можете определить их явно.

void ICollection.Clear() {
    // ...
}

Явно определенные члены доступны, только если экземпляр используется через этот интерфейс.

YourCollection col1 = new YourCollection();
col1.Clear(); // this is not allowed if clear is defined explicitly

ICollection col2 = new YourCollection();
col2.Clear(); // this will work because col2 is ICollection
...