我知道从另一个类继承的类可能会使用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; }
}
答案 0 :(得分:23)
是否有任何实际的理由在实现其他接口的接口中隐藏成员?
不确定。 BCL本身使用这种模式的事实表明该模式是实用的。例如:
interface IEnumerable
{
IEnumerator GetEnumerator();
}
interface IEnumerable<T> : IEnumerable
{
new IEnumerator<T> GetEnumerator();
}
IEnumerable<T>
的设计者希望与IEnumerable
向后兼容,但也希望确保通用接口上GetEnumerator
的每次使用都称为通用版本。在这种情况下,隐藏是适当的机制。
关于方法隐藏的细微之处的一些额外讨论,请参阅:
http://blogs.msdn.com/b/ericlippert/archive/2008/05/21/method-hiding-apologia.aspx
答案 1 :(得分:7)
我发现隐藏基本成员有用的一个案例是当你有一个基本接口,它在属性上公开一个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; }
}
答案 2 :(得分:2)
接口不能完全隐藏父接口,但实现类可以,这可能很有用。
考虑一个类MyStringList
,它是一个实现IList<string>
的只读列表。为简单起见,我们将它作为一个简单的传递:一些成员是毫无意义的,所以我们可以这样做:
//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<string>.this[int index]
{
get
{
return this[index];
}
set
{
throw new NotSupportedException("Collection is read-only.");
}
}
//hide some pointless ones.
bool ICollection<string>.IsReadOnly
{
get
{
return true;
}
}
void IList<string>.Insert(int index, string item)
{
throw new NotSupportedException("Collection is read-only.");
}
void IList<string>.RemoveAt(int index)
{
throw new NotSupportedException("Collection is read-only.");
}
void ICollection<string>.Add(string item)
{
throw new NotSupportedException("Collection is read-only.");
}
void ICollection<string>.Clear()
{
throw new NotSupportedException("Collection is read-only.");
}
bool ICollection<string>.Remove(string item)
{
throw new NotSupportedException("Collection is read-only.");
}
处理MyStringList
到IList<string>
界面的人必须能够调用这些毫无意义的成员,但是没有必要与MyStringList
打交道。
现在,有了这个可能的类,接口可以通过名称匹配父接口强制这样的含义。类示例为IEnumberable<T>
,其中GetEnumerator()
与其继承的IEnumerable
匹配。因此,类可以隐式地只实现一个,并且必须隐藏另一个或两个(因为总是可以将结果(IEnumerator<T>
)转换为另一个的结果类型(IEnumerator
)然后最明智的行为通常是隐式实现IEnumberable<T>
版本,并明确地实现IEnumerable
一个(通常通过返回另一个的结果)。
然而,虽然隐藏的力量至少有一个被隐藏,但没有什么可以强制选择哪个(如果有的话)是隐式实现的,除了一个具有如此明显的优势而另一个没有那么少的人。
答案 3 :(得分:1)
隐藏继承的成员不应该故意作为设计的一部分。语言允许隐藏方法,以防止祖先(在库的主要版本中)发生更改,从而破坏恰好已经定义了相同名称的成员的后代。
也就是说,有时使用返回更具体类型的等效方法隐藏继承的方法很方便。在这些情况下,你唯一要做的就是强制转换糖 - 注意不要改变方法的语义,因为调用者可能很容易调用祖先方法而不是你的方法。
另请参阅:Is there ever a situation where derived class should hide …?
答案 4 :(得分:0)
我想如果你要明确地实现IChildInterface,可能会出现你想要隐藏PropertyA的情况(可能?)