C# 显式重写基类型的虚拟接口方法
本文关键字:虚拟 接口 方法 类型 基类 重写 | 更新日期: 2023-09-27 17:56:47
我有一个抽象类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();
}
但是由于数据字典是一个IDictionary,因此IEnumerable<KeyValuePair<string, DataBase>>
,我遇到了无法覆盖数据库GetEnumerator()
的问题。我尝试了许多不同的方法:
(public|protected) (override) IEnumerator<DataBase> DataBase.GetEnumerator()
(public|protected) (override) IEnumerator<DataBase> IEnumerable<DataBase>.GetEnumerator()
修饰符"覆盖"对此项无效 (CS0106)
现在,我不确定在这个问题上要寻找什么 - 这叫什么?- 或者哪个限制(如果有的话)阻止我做我想做的事情以及为什么它可能在那里。
相关问题和解答"C# 重写基类的接口协定方法"不能解决问题。如果你要把x
的类型改为TestBase
,代码输出"Base"。
C# 规范在第 13.4.1 节中明确禁止在显式实现的接口成员上使用override
:
显式接口成员实现包含访问修饰符是编译时错误,包含修饰符
abstract
、virtual
、override
或static
是编译时错误。
因此,如果要覆盖DataDictionary
中的DataBase::GetEnumerator()
,则需要非显式实现。但是为了使用非显式实现编写覆盖,您必须显式实现IEnumerable<KeyValuePair<string, DataBase>>::GetEnumerator()
,因为如果您为该方法使用非显式实现,它将隐藏DataBase::GetEnumerator()
,因为这两种方法仅在返回类型上有所不同。
一句话:我不明白你为什么要设计这样的东西。(当你把它描述为"做一些太愚蠢和复杂的事情"时,你似乎在你的回答中得出了同样的结论!
现在,我以前遇到过这类问题,这通常是做一些太愚蠢和复杂的事情。我能想到的一个明显的解决方案是直接将实现移动到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();
}
但显然,这绝对不是最干净的解决方案。