C#显式覆盖基类型的虚接口方法
C# Explicitly override virtual interface method of base type
我有一个抽象 class DataBase
用作不同类型数据的基础 class,例如简单值类型 (byte
, int
、string
等)和更复杂的数据结构,如 DataList
和 DataDictionary
。 DataList 实现 IList<DataBase>
和 DataDictionary 实现 IDictionary<string, DataBase>
.
为了简单起见,我继续将一些我经常使用的东西放在数据库中 class,因此不需要转换:
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];
这些方法随后在基础 classes 中被覆盖。或者不是,在这种情况下它会在使用时抛出异常。为了使事情更简单一些,我还想以类似的方式实现 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>>
,我 运行 遇到了无法覆盖数据库 GetEnumerator()
的问题。我尝试了多种不同的方式:
(public|protected) (override) IEnumerator<DataBase> DataBase.GetEnumerator()
(public|protected) (override) IEnumerator<DataBase> IEnumerable<DataBase>.GetEnumerator()
The modifier 'override' is not valid for this item (CS0106)
现在,我不确定关于这个问题要寻找什么 - 这甚至叫什么? - 或者是哪个限制(如果有的话)阻止我做我想做的事情,以及为什么会出现这种情况。
相关问答"C# overriding an interface contract method of a base class"没有解决问题。如果您要将 x
的类型更改为 TestBase
,代码输出 "Base".
现在,我以前 运行 遇到过这类问题,这通常是 做某事太傻太复杂的情况.我能想到的一个明显的解决方案是将实现直接移动到 DataBase
class 中:
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();
}
但显然,这绝对不是最干净的解决方案。
C# 规范明确禁止在 13.4.1 节中明确实现的接口成员上使用 override
:
It is a compile-time error for an explicit interface member implementation to include access modifiers, and it is a compile-time error to include the modifiers abstract
, virtual
, override
, or static
.
所以如果你想覆盖 DataDictionary
中的 DataBase::GetEnumerator()
,你需要一个非显式的实现。但是为了使用非显式实现编写覆盖,您必须显式实现 IEnumerable<KeyValuePair<string, DataBase>>::GetEnumerator()
,因为如果您对 that 方法使用非显式实现,它将隐藏 DataBase::GetEnumerator()
,因为这两种方法仅在 return 类型上有所不同。
底线:我不明白你为什么要设计这样的东西。 (当您将其描述为“doing-something-way-too-silly-and-complicated!”)
时,您似乎在回答中得出了相同的结论
我有一个抽象 class DataBase
用作不同类型数据的基础 class,例如简单值类型 (byte
, int
、string
等)和更复杂的数据结构,如 DataList
和 DataDictionary
。 DataList 实现 IList<DataBase>
和 DataDictionary 实现 IDictionary<string, DataBase>
.
为了简单起见,我继续将一些我经常使用的东西放在数据库中 class,因此不需要转换:
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];
这些方法随后在基础 classes 中被覆盖。或者不是,在这种情况下它会在使用时抛出异常。为了使事情更简单一些,我还想以类似的方式实现 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>>
,我 运行 遇到了无法覆盖数据库 GetEnumerator()
的问题。我尝试了多种不同的方式:
(public|protected) (override) IEnumerator<DataBase> DataBase.GetEnumerator()
(public|protected) (override) IEnumerator<DataBase> IEnumerable<DataBase>.GetEnumerator()
The modifier 'override' is not valid for this item (CS0106)
现在,我不确定关于这个问题要寻找什么 - 这甚至叫什么? - 或者是哪个限制(如果有的话)阻止我做我想做的事情,以及为什么会出现这种情况。
相关问答"C# overriding an interface contract method of a base class"没有解决问题。如果您要将 x
的类型更改为 TestBase
,代码输出 "Base".
现在,我以前 运行 遇到过这类问题,这通常是 做某事太傻太复杂的情况.我能想到的一个明显的解决方案是将实现直接移动到 DataBase
class 中:
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();
}
但显然,这绝对不是最干净的解决方案。
C# 规范明确禁止在 13.4.1 节中明确实现的接口成员上使用 override
:
It is a compile-time error for an explicit interface member implementation to include access modifiers, and it is a compile-time error to include the modifiers
abstract
,virtual
,override
, orstatic
.
所以如果你想覆盖 DataDictionary
中的 DataBase::GetEnumerator()
,你需要一个非显式的实现。但是为了使用非显式实现编写覆盖,您必须显式实现 IEnumerable<KeyValuePair<string, DataBase>>::GetEnumerator()
,因为如果您对 that 方法使用非显式实现,它将隐藏 DataBase::GetEnumerator()
,因为这两种方法仅在 return 类型上有所不同。
底线:我不明白你为什么要设计这样的东西。 (当您将其描述为“doing-something-way-too-silly-and-complicated!”)
时,您似乎在回答中得出了相同的结论