Reputation: 31640
I'm not sure what I'm wanting to do is even a good idea, but here's the problem anyway: I have MyClass
which I want to implement two different types of the generic IEnumerable
class, e.g.
public class MyClass : IEnumerable<KeyValuePair<string, string>>,
IEnumerable<KeyValuePair<MyEnum, string>>
Now, the problem with doing this is when I try to define necessary methods from the interfaces, the compiler complains "Type 'MyClass' already defines a member called 'GetEnumerator' with the same parameter types". This is because I have these two methods:
public IEnumerator<KeyValuePair<MyEnum, string>> GetEnumerator() { ... }
public IEnumerator<KeyValuePair<string, string>> GetEnumerator() { ... }
I have to have GetEnumerator()
with no parameters because of the interface, and the only thing that differs is the return type, which is not allowed.
Here are what I see as my options:
IEnumerable
generic type which MyClass
would implement, and then just adding extra methods that differ by parameters and not just return type (e.g. Add
), without implementing the extra generic interfaces.MyClass
, call it MyBaseClass<T>
, and it would implement IEnumerable<KeyValuePair<T, string>>
. Then, I would have different versions of MyClass
, e.g. MyClass<string>
and MyClass<MyEnum>
.Which seems preferable here, or am I missing something that would be an even better solution?
Upvotes: 2
Views: 4748
Reputation: 10307
You can explicity implement each interface like this:
IEnumerable<KeyValuePair<string, string>> IEnumerable<KeyValuePair<string, string>>.GetEnumerator() { ... }
IEnumerator<KeyValuePair<MyEnum, string>> IEnumerator<KeyValuePair<MyEnum, string>>.GetEnumerator() { ... }
Upvotes: 2
Reputation: 4005
You can use explicit interface declarations in order to get different implementations for each of the two interfaces that you are implement. For example:
public class MyClass : IEnumerable<KeyValuePair<string, string>>,
IEnumerable<KeyValuePair<MyEnum, string>>
{
IEnumerator<KeyValuePair<MyEnum, string>> IEnumerable<KeyValuePair<MyEnum, string>>.GetEnumerator()
{
// return your enumerator here
}
IEnumerator<KeyValuePair<string, string>> IEnumerable<KeyValuePair<string, string>>.GetEnumerator()
{
// return your enumerator here
}
IEnumerator IEnumerable.GetEnumerator()
{
var me = this as IEnumerable<KeyValuePair<string, string>>;
return me.GetEnumerator();
}
}
However, because IEnumerable<> derives from IEnumerable, you'll have to pick which one you want to return from the IEnumerable.GetEnumerator() call.
Upvotes: 14
Reputation: 47587
One option would be to implement interfaces explicitly.
Downside - you would always need to cast MyClass.
Upvotes: 0
Reputation: 99869
You can use explicit interface implementation to implement interfaces with conflicting methods. However, if you implement two IEnumerable<T>
interfaces, it will cause some rather annoying issues for things like foreach
loops. I once tried this for something and promptly went back to implementing 1 IEnumerable
interface, and offering the other as a property of the object.
Upvotes: 2