-1

I'm trying to design an API that is supposed to have a certain method for each of the 20+ concrete classes that I need to support (I can't change those specs).

My first idea was to use overloading to have the same method with different parameters and being able to automatically invoke the correct one based on the concrete class, however I'm getting the error in the title and I was wondering if there was a better way to do this (without having to use if/switch on object's type).

Here's a quick pseudo-code example:

class BaseClass {}
class ChildClassA : BaseClass {}
class ChildClassB : BaseClass {}

class Factory {

    public static void Build(ChildClassA obj){}
    public static void Build(ChildClassB obj){}

}

class Main {

    public static void Main(string[] args){
        BaseClass obj = getFromSomewhereRemote();
        Factory.Build(obj); // This is the line where I get the error
    }

}

I understand that I could build a method like this one:

void Build(BaseClass obj){

    switch (obj){
        case BaseClassA objA:
            Build(objA);
            break;
        ....
    }

}

but I was wondering if I could have the same results without switching on types.

STT
  • 215
  • 1
  • 11
  • `= new ChildClassA();` types the `var` as `ChildClassA`, and given that you have these overloads (`Build(ChildClassA obj)` etc) for each type, I don't see how you could be getting that error with this code. – GSerg May 06 '19 at 10:44
  • There is no `Build()` method in class `Main` – Cid May 06 '19 at 10:45
  • 1. No `Build()` in `Main` 2. `Factory.Build` has private access. – Lesiak May 06 '19 at 10:47
  • What exactly does your `Build` method do? Is it the same for each class? – wake-0 May 06 '19 at 11:07
  • "the error", which error do you get exactly? – Lasse V. Karlsen May 06 '19 at 11:23
  • @LasseVågsætherKarlsen "Cannot convert from 'typeA' to 'typeB'". – GSerg May 06 '19 at 11:24
  • Can you post a [mcve]? The code in your question would simply state that there is no method on the Program type called Build, so that won't work. I want to see how you're attempting to call the method on the Factory type, because that's not what you're doing right now. – Lasse V. Karlsen May 06 '19 at 11:24
  • The code in your question produces the compiler error "CS0103 The name 'Build' does not exist in the current context", meaning that the code in your question is not the code you're actually using, that produces that error message. Please post actual code that produces that error message. – Lasse V. Karlsen May 06 '19 at 11:26
  • And if you make the two Build methods in Factory public, then change the code in main to be: `new Factory().Build(obj);` it will not produce that error. Again, please post code that actually produces this error message. – Lasse V. Karlsen May 06 '19 at 11:27
  • @Gserg: you're right, the example was a bad one. I edited it to make it clearer based on my requirements. – STT May 06 '19 at 12:10
  • Why even with edit didn't you bother to provide correct code ? `Factory.Build` implies a static method which doesn't match what you provided inside the `Factory` class. In general I don't think it's enough to provide a pseudo code If you want an assistance with a compilation error. – Dmytro Mukalov May 06 '19 at 12:20
  • @DmytroMukalov because I can't provide any code as I'm not its owner. Why would you need the exact code for something like that? Does adding `static` to both `Build` methods make the question easier to understand? – STT May 06 '19 at 12:25
  • Because code you provided doesn't behave in way you stated, which most likely indicates that you omitted some details. A verifiable example will make the question easier to understand and the fact that your code isn't compilable per se, and minor changed to make it compilable don't make the problem reproducible, means that you code isn't verifiable. – Dmytro Mukalov May 06 '19 at 12:34
  • _Because code you provided doesn't behave in way you stated, which most likely indicates that you omitted some details._ It's not true. Pasted [here](https://dotnetfiddle.net/VNM3Rj) after adding `public static` to `Build` methods, here you have the error on line 18. I think you're all focusing on the wrong thing in this question. – STT May 06 '19 at 12:40
  • Ok, in the first edition there was explicit `ChildClassA` construction, now I see it's changed - I missed this piece. – Dmytro Mukalov May 06 '19 at 12:45
  • I'm not sure what the `Build` methods are supposed to do but as they can be candidates to be a part of `BaseClass` as they are used in dynamic binding. – Dmytro Mukalov May 06 '19 at 12:52
  • Each child class has a different logic for the `Build` method. EDIT: I can't change anything in those classes. – STT May 06 '19 at 12:55

1 Answers1

2

Although not recommended, but you can do something like this with dynamic keyword. Dynamic uses reflection under the hood so there is a performance issue. This will avoid lot of if statements. Runtime will decide which method will take.

 void Build(ChildClassA obj)
 {
     obj.MethodA();
 }

 void Build(ChildClassB obj)
 {
     obj.MethodB();
 }

And call:

Build((dynamic) baseClassObj);
GSerg
  • 76,472
  • 17
  • 159
  • 346
Gauravsa
  • 6,330
  • 2
  • 21
  • 30
  • I didn't think about using `dynamic`. If the performance hit is not that big, I might consider it instead of writing countless if statements. – STT May 06 '19 at 12:26