How to hide some members of an interface

2019-01-19 16:40发布

问题:

I would like to create a custom collection that implements ICollection.

But I would like not to expose some memebers of ICollection like Clear method.

How to achieve this?

回答1:

You can implement the interface explicitly and have the implementation hidden:

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

The user can't call urClassInstance.Clear() directly, but they can call ((ICollection)urClassInstance).Clear() indirectly like this.



回答2:

You could make it empty or launch a NotImplementedException



回答3:

You can't. Interface members are always public... otherwise, the class would fail to implement the interface. That's why access modifiers are not allowed in interface member declarations.

There are two ways of declaring members that satisfy the interface requirements: implicitly and explicitly.

Implicitly, any public member with a matching signature will be used:

public interface IGuess
{
    void Guess();
}

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

This is a "normal" member of the class and will be reflected on instances of the type.

You can also, as @Jaroslav points out, explicitly designate members as satisfying an interface definition:

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

In this case, the member will not appear unless the instance is cast to the interface type. It is still public.



回答4:

You might want to look into the ReadOnlyCollection. You could make a private innerclass and let it implement ICollection. Then Make a method that returns ReadOnlyCollection by calling AsReadOnly on that object. Or just subclass it if that fits your design. It is preferred to subclass this collection rather than try to create your own implementation.



回答5:

If you just want to hide those members from your own collection's interface, you can define them explicitly.

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

Explicitly defined members are only available if the instance is used through that interface.

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


回答6:

What makes you so sure that you really need to implement ICollection? If you don't want some methods from this interface, don't use it, declare a new interface with methods that you want. The whole point of using ICollection is to make other objects think that they can do with your object whatever they can do with any other collection.



回答7:

I would rather suggest you to consider "Composition" over "Inheritance" here.

That gives you more control over what all to expose to the outer world, with added advantage of dynamic binding with the actual collection.