【问题标题】:C# Explicitly override virtual interface method of base typeC#显式覆盖基类型的虚拟接口方法
【发布时间】:2015-06-16 16:21:35
【问题描述】:

我有一个抽象类DataBase,它用作不同类型数据的基类,例如简单值类型(byteintstring 等)和更复杂的数据结构,例如@ 987654326@ 和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&lt;KeyValuePair&lt;string, DataBase&gt;&gt;,我遇到了无法覆盖 DataBase 的 GetEnumerator() 的问题。我尝试了许多不同的方法:

(public|protected) (override) IEnumerator<DataBase> DataBase.GetEnumerator()
(public|protected) (override) IEnumerator<DataBase> IEnumerable<DataBase>.GetEnumerator()

修饰符“覆盖”对此项无效 (CS0106)

现在,我不知道该寻找什么来解决这个问题 - 这叫什么? - 或者哪个限制(如果有的话)阻止我做我想做的事情以及为什么它可能存在。


相关问答"C# overriding an interface contract method of a base class"没有解决问题。如果您要将x 的类型更改为TestBase,代码会输出“Base”。

【问题讨论】:

    标签: c# inheritance overriding


    【解决方案1】:

    C# 规范明确禁止在 13.4.1 部分中明确实现的接口成员上使用 override

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

    所以如果你想在DataDictionary 中覆盖DataBase::GetEnumerator(),你需要一个非显式的实现。但是为了使用非显式实现编写覆盖,您必须显式实现IEnumerable&lt;KeyValuePair&lt;string, DataBase&gt;&gt;::GetEnumerator(),因为如果您对that方法使用非显式实现,它将隐藏DataBase::GetEnumerator(),因为这两种方法的区别仅在于它们的返回类型。

    底线:我不明白你为什么要设计这样的东西。 (当您将其描述为“doing-something-way-too-silly-and-complicated!”时,您的回答似乎得出了相同的结论)

    【讨论】:

    • 我想我通过实验得出了同样的结论。感谢您在规范中提到这一点的发现。在这些情况下,我绝对应该检查自己。
    【解决方案2】:

    现在,我以前遇到过这类问题,这通常是做某事的方式过于愚蠢和复杂的情况。我能想到的一个明显的解决方案是将实现直接移到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();
    }
    

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

    【讨论】:

      猜你喜欢
      • 2012-12-04
      • 1970-01-01
      • 1970-01-01
      • 2011-05-21
      • 2011-03-15
      • 2013-01-15
      • 1970-01-01
      • 1970-01-01
      • 2018-01-28
      相关资源
      最近更新 更多