我有一个抽象类DataBase
,它用作不同类型数据的基类,例如简单值类型(byte
,int
,string
等。 )和更复杂的数据结构,如DataList
和DataDictionary
。 DataList实现IList<DataBase>
,DataDictionary实现IDictionary<string, DataBase>
。
为了简单起见,我继续并在DataBase类中添加了一些我经常使用的东西,因此无需进行强制转换:
public virtual DataBase this[string name] {
get { throw new NotSuppportedException(); }
set { throw new NotSuppportedException(); }
}
public virtual DataBase this[int index] { ...
// Example usage:
var someData = rootData["SomeList"][10];
然后在基类中重写这些方法。或者不是,在这种情况下,它会在使用时抛出异常。为了使事情变得更简单,我还希望以类似的方式实现IEnumerable<DataBase>
:
public virtual IEnumerator<DataBase> GetEnumerator() {
throw new NotSuppportedException();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
return GetEnumerator();
}
但由于DataDictionary是一个IDictionary,因此IEnumerable<KeyValuePair<string, DataBase>>
,我遇到了无法覆盖DataBase GetEnumerator()
的问题。我尝试了很多不同的方法:
(public|protected) (override) IEnumerator<DataBase> DataBase.GetEnumerator()
(public|protected) (override) IEnumerator<DataBase> IEnumerable<DataBase>.GetEnumerator()
修饰符&#39;覆盖&#39;对此项目无效(CS0106)
现在,我不确定在这个问题上该寻找什么 - 这甚至叫做什么? - 或者哪种限制(如果有的话)阻止我做我想做的事以及为什么会这样做。
相关问答"C# overriding an interface contract method of a base class"并未解决问题。如果您要将x
的类型更改为TestBase
,则代码会输出&#34; Base&#34;。
答案 0 :(得分:1)
C#规范明确禁止在13.4.1部分中明确实现的接口成员上使用override
:
显式接口成员实现包含访问修饰符是编译时错误,包含修饰符
abstract
,virtual
,override
是编译时错误,或static
。
因此,如果要覆盖DataBase::GetEnumerator()
中的DataDictionary
,则需要非显式实现。但是为了使用非显式实现编写覆盖,您必须已明确实现IEnumerable<KeyValuePair<string, DataBase>>::GetEnumerator()
,因为如果对 方法使用非显式实现,它将隐藏{{ 1}},因为这两种方法的区别仅在于它们的返回类型。
结论:我不明白你为什么要设计这样的东西。 (当你把它描述为&#34; 做某事太过愚蠢和复杂的事情时,你的回答似乎得出了同样的结论!&#34;)
答案 1 :(得分:0)
现在,我之前遇到过这类问题,这通常是做某事 - 过于愚蠢和复杂的情况。我能想到的一个明显的解决方案是直接将实现转移到DataBase
类:
public IEnumerator<DataBase> GetEnumerator() {
if (this is DataList)
return ((DataList)this).GetEnumerator();
else if (this is DataDictionary)
return ((DataDictionary)this).Values.GetEnumerator();
else throw new NotSupportedException();
}
但显然,它绝对不是最干净的解决方案。