C# 显式重写基类型的虚拟接口方法

本文关键字:虚拟 接口 方法 类型 基类 重写 | 更新日期: 2023-09-27 17:56:47

我有一个抽象类DataBase它用作不同类型数据的基类,例如简单的值类型(byteintstring等)和更复杂的数据结构,如DataListDataDictionary。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# 显式重写基类型的虚拟接口方法

C# 规范在第 13.4.1 节中明确禁止在显式实现的接口成员上使用override

显式接口成员实现包含访问修饰符是编译时错误,包含修饰符abstractvirtualoverridestatic是编译时错误。

因此,如果要覆盖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();
}

但显然,这绝对不是最干净的解决方案。