1

If we have two interfaces with a common base that a class must implement, is it possible to explicitly implement the common base?

Consider IEnumerable<T> for example:

public class MyMultiEnumerable: IEnumerable<int>, IEnumerable<double>
{
    private readonly List<int> intList = new List<int>();
    private readonly List<double> doubleList = new List<double>();

    IEnumerator<double> IEnumerable<double>.GetEnumerator()
    {
        return doubleList.GetEnumerator();
    }
    IEnumerator<int> IEnumerable<int>.GetEnumerator()
    {
        return intList.GetEnumerator();
    }

    public IEnumerator GetEnumerator()
    {
        /*
         * How do we deal with this common case, where in context it means
         * two different things?
         */
        throw new System.NotImplementedException();
    }
}

I have no requirement to do so, but I am interested from a theoretical perspective.

Update #1

I think my use of IEnumerable and basic types is conflating this, and after thinking about it some more, I believe it could be stripped back to this problem:

public interface CommonBase
{
    void CommonMethod();
}

public interface AltBase1 : CommonBase
{
    void UnommonMethod();
}

public interface AltBase2 : CommonBase
{
    void UnommonMethod();
}

public class Example : AltBase1, AltBase2
{
    public void CommonMethod()
    {
        /*
         * If this method needs to know whether it is being called on behalf
         * of AltBase1 or AltBase2, how could it determine the implementation?
         */
    }

    void AltBase2.UnommonMethod()
    {

    }

    void AltBase1.UnommonMethod()
    {

    }
}

Because it doesn't appear possible to explicitly implement an interface's inherited members (Example of how this might look below). I strongly believe this isn't possible via any conventional means, as it appears to be a multiple inheritance problem.

void AltBase1.CommonBase.CommonMethod()
{
    // AltBase1 targeted Implementation
}

Could it be achieved via any Meta-based approach, or not at all?

Élie
  • 1,285
  • 1
  • 12
  • 27
  • The problem is that it's confusing for the end-user, why not leverage a paradigm like `IConvertible` instead ? – aybe Jan 24 '18 at 04:07
  • I have had the realisation that my problem is probably completely invalid. In my use case the class would either be treated explicitly as an `IEnumerable` or `IEnumerable`, and never as an `IEnumerable`. Since the method names are the same `IEnumerator.GetEnumerator()` should never be called, and an `InvalidOperationException` or similar should be thrown. I need to mull over this some more. – Élie Jan 24 '18 at 04:28
  • Your code might not but say, if you use LINQ, it will at some point. By the way, `IEnumerator GetEnumerator` is generally implemented as simply returning the result of the specialized overload. TL;DR you must implement both overloads. – aybe Jan 24 '18 at 04:33
  • Sure it's possible. And back before `IEnumerable` was made covariant in [c# 4.0](https://stackoverflow.com/q/6732299) you would sometimes see classes that implement, say, `IEnumerable` and `IEnumerable` Usually the generic with the most derived parameter would be directly implemented and the generic with the base parameter would be explicit. `IEnumerable` and `IEnumerable` would be very strange though -- and would confuse almost all serializers. – dbc Jan 24 '18 at 06:09

2 Answers2

0

I'm not sure if it's possible, but I think it's a code smell. The only scenario where this is viable is as you've phrased it - when implementing a specific version for a generic class. In that scenario, you should be leveraging the type variables, rather than how you've got it right now.

kolosy
  • 3,029
  • 3
  • 29
  • 48
0

So you can get it to a point where you can compile your code. From the IEnumerable interface you have to implement GetEnumerator(), but you have to decide if you want to return intList or doubleList. Both IEnumerable<int> and IEnumerable<double> have the same signature on GetEnumerator() so there's no way to implement them both since the compiler will complain.

Take a look at this post as it has good compatible/incompatible examples of how to deal with interfaces with the same method.

Implementing two interfaces in a class with same method. Which interface method is overridden?

Bae
  • 88
  • 6