-1

I am certain that I simply do not know the name for what I am trying to do, otherwise my googling would be more successful. I currently only find results pertaining to interfaces with same named methods.

I have a few classes that inherit from a common base class and some implement an interface. I have methods accepting the base class or the interface as a parameter. I cannot compile since this causes ambiguity with the error

the call is ambiguous between the following methods or properties: DoThings(IQueryable<A>) and DoThings(IQueryable<B>)` on the call in ConcreteExecutionClass.

Furthermore, generics won't work because type constraints on generics do not make a unique method signature.

Is there a way (or an acceptable pattern) to force the execution to a specific method based on parameter types?

public abstract class A {
    // some properties
}

public class ConcreteA : A {
    // full implementation
}

public interface B {
    // a property
}

public class ConcreteAB : A, B {
    // full implementation
}

public abstract class ExecutionClass {
    public IQueryable<A> DoThings(IQueryable<A> content){
        return A.method().AsQueryable();
    }

    public IQueryable<B> DoThings(IQueryable<B> content){
        return B.interfaceRequiredMethod().method().AsQueryable();
    }
}

public class ConcreteExecutionClass : ExecutionClass {
    public void Program(){
        var objectList = new List<ConcreteAB>{/*....*/};
        DoThings(objectList);
    }
}

Each of the concrete classes has a class managing linq queries on lists of objects, which each call DoThings(). The goal is to keep the actual implementation of DoThings() transparent to the concrete classes.

I have attempted covariance in the interface, however have been unable to avoid inheriting A which forces down the first code path.

The code above is a simplification of the actual implementation. There are about 10 classes deriving solely from A and 4 deriving from A and B.

Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
jeubank12
  • 891
  • 9
  • 17
  • 1
    Which method do you expect to be called for `ConcreteAB`? And why? – Rob Dec 11 '17 at 03:15
  • 1
    You may refer to https://stackoverflow.com/questions/42078610/c-sharp-generic-method-resolution-fails-with-an-ambiguous-call-error/42078735#42078735 – Dev Dec 11 '17 at 03:23
  • @Ryu that post is why I said that generics don't work – jeubank12 Dec 11 '17 at 03:29
  • @Rob I want the DoThings(B) to be called. I understand why it is ambiguous and am looking for a solution. I am thinking about trying to cast ConcreteAB to B when it is passed as a parameter, however this doesn't make it transparent to the ConcreteExecution class – jeubank12 Dec 11 '17 at 03:32
  • Then your only option is to have a third overload; C. Where C is an abstract class subclassing A and implementing B. Though your design overwhelmingly seems to be a bad idea. – Rob Dec 11 '17 at 03:40
  • 1
    I you want DoThings(B) to be called then you could type cast it , no problem at all. Since there is a ambiguity you can certainly help run time to solve this using type casting. – CreativeManix Dec 11 '17 at 03:46
  • 1
    I'm reading this using my cellphone so perhaps I'm missing something critical here, but it seems to me like an explicit interface implementation should solve this problem. – Zohar Peled Dec 11 '17 at 04:43
  • @ZoharPeled no, it is not an interface implementation problem, it is an overload resolution problem – jeubank12 Dec 11 '17 at 15:52
  • Yeah, after another read on my computer I understand your problem better. Upvoted your asnwer, though it seems a bit more like a workaround then a solution :-) – Zohar Peled Dec 11 '17 at 15:56
  • @ZoharPeled unfortunately I am stuck with this implementation. Trying to add functionality to an api where I don't have access to all the controllers but I do have access to an abstract controller they all inherit from. – jeubank12 Dec 11 '17 at 15:59

1 Answers1

0

I simply created an abstract hierarchy where abstract A is the base and there are 2 abstract classes inheriting from it.

jeubank12
  • 891
  • 9
  • 17