有没有理由在界面中隐藏inheritance的成员?
我知道从另一个类inheritance的类可能会使用new
关键字隐藏属性。 但是,这隐藏了属性的特定实现,因此我可以看到它是如何使用的。
是否有任何实际的理由在实现其他接口的接口中隐藏成员? 例如,考虑下面的例子。 IChildInterface
实现了IParentInterface
,并隐藏了PropertyA
。
interface IParentInterface { string Name { get; set; } int PropertyA { get; set; } int PropertyB { get; set; } } interface IChildInterface : IParentInterface { int PropertyA { get; set; } int PropertyC { get; set; } }
是否有任何实际的理由在实现其他接口的接口中隐藏成员?
当然。 BCL本身使用这种模式的事实表明该模式是实用的。 例如:
interface IEnumerable { IEnumerator GetEnumerator(); } interface IEnumerable : IEnumerable { new IEnumerator GetEnumerator(); }
IEnumerable
的设计者希望与IEnumerable
向后兼容,但也希望确保通用接口上的GetEnumerator
每次使用都称为通用版本。 在这种情况下,隐藏是适当的机制。
关于方法隐藏的细微点的一些额外讨论,请参阅:
http://blogs.msdn.com/b/ericlippert/archive/2008/05/21/method-hiding-apologia.aspx
我发现隐藏基本成员有用的一个案例是当你有一个基本接口,它在属性上公开一个getter但是派生接口想要暴露一个setter:
public interface IBase { int MyProperty { get; } } public interface IDerive : IBase { // you need to specify the getter here too new int MyProperty { get; set; } }
接口不能完全隐藏父接口,但实现类可以,这可能是有用的。
考虑一个类MyStringList
,它是一个实现IList
的只读列表。 为简单起见,我们将它作为一个简单的传递:一些成员是毫无意义的,所以我们可以这样做:
//implement this one implicitly, as it's useful. public int Count { return _list.Count; } //do a half-and-half on the indexer public string this[int index] { get { return _list[index]; } } string IList.this[int index] { get { return this[index]; } set { throw new NotSupportedException("Collection is read-only."); } } //hide some pointless ones. bool ICollection .IsReadOnly { get { return true; } } void IList .Insert(int index, string item) { throw new NotSupportedException("Collection is read-only."); } void IList .RemoveAt(int index) { throw new NotSupportedException("Collection is read-only."); } void ICollection .Add(string item) { throw new NotSupportedException("Collection is read-only."); } void ICollection .Clear() { throw new NotSupportedException("Collection is read-only."); } bool ICollection .Remove(string item) { throw new NotSupportedException("Collection is read-only."); }
通过IList
接口处理MyStringList
必须能够调用这些无意义的成员,但是没有必要处理MyStringList
人这样做。
现在,有了这个可能的类,接口可以通过名称匹配父接口强制这样的含义。 类示例是IEnumberable
,其中GetEnumerator()
与它inheritance的IEnumerable
匹配。 因此,类可以隐式地只实现一个,并且必须隐藏另一个或两个(因为总是可以将结果( IEnumerator
)转换为另一个( IEnumerator
)的结果类型,那么最明智的行为通常是隐式实现IEnumberable
版本,并显式实现IEnumerable
一个(通常通过返回另一个的结果)。
然而,虽然隐藏的力量至少有一个被隐藏,但是没有什么可以强制选择哪个(如果有的话)是隐式实现的,除了一个具有如此明显的优势而另一个没有其他人可以做到的优势之外。
隐藏inheritance成员不应该故意作为设计的一部分。 语言允许隐藏方法,以防止祖先(在库的主要版本中)发生更改,从而破坏恰好已经定义了相同名称的成员的后代。
也就是说,有时使用返回更具体类型的等效方法隐藏inheritance的方法很方便。 在这些情况下,你唯一要做的就是强制转换糖 – 注意不要改变方法的语义,因为调用者可能很容易调用祖先方法而不是你的方法。
另请参阅: 是否存在派生类应隐藏的情况?
我想如果你要明确地实现IChildInterface,可能会有一个你想要隐藏PropertyA的情况(也许?)