I have an abstract class DataBase
which is used as base class for different types of data, such as simple value types (byte
, int
, string
etc.) and more complex data structures like DataList
and DataDictionary
. DataList implements IList<DataBase>
and DataDictionary implements IDictionary<string, DataBase>
.
For simplicity's sake, I went ahead and put a couple of things I'll often use in the DataBase class, so casting won't be necessary:
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];
These methods are then overridden in base classes. Or not, in which case it throws the exception when used. To make things a little simpler I also wanted to implement IEnumerable<DataBase>
in a similar way:
public virtual IEnumerator<DataBase> GetEnumerator() {
throw new NotSuppportedException();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
return GetEnumerator();
}
But since DataDictionary is an IDictionary, and therefore IEnumerable<KeyValuePair<string, DataBase>>
, I've run into the issue of not being able to override DataBase's GetEnumerator()
. I've tried a number of different ways:
(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)
Now, I wasn't sure what to look for regarding this issue - what is this called even? - or which limitation (if any) is preventing me from doing what I'm trying to do and why it may be there.
Related question and answer "C# overriding an interface contract method of a base class" does not solve the issue. If you were to change x
's type to TestBase
, the code outputs "Base".
The C# spec explicitly disallows the use of
override
on an explicitly implemented interface member in section 13.4.1:So if you want to override
DataBase::GetEnumerator()
inDataDictionary
, you need a non-explicit implementation. But in order to write an override using a non-explicit implementation, you must have explicitly implementedIEnumerable<KeyValuePair<string, DataBase>>::GetEnumerator()
, because if you use a non-explicit implementation for that method, it will hideDataBase::GetEnumerator()
, since the two methods differ only by their return types.Bottom line: I can't see why you'd want to design something like this. (You seem to have arrived at the same conclusion in your answer when you described it as "doing-something-way-too-silly-and-complicated!")