-2

I think the below code says it all.

// Example A
switch (id)
{
  case 1:
    return await Callout<ClassA>(a, b, c, d, e, f, g, h, i, j, k, l, m);
  case 2:
    return await Callout<ClassB>(a, b, c, d, e, f, g, h, i, j, k, l, m);
  case 3:
    return await Callout<ClassC>(a, b, c, d, e, f, g, h, i, j, k, l, m);
  case 4:
    return await Callout<ClassD>(a, b, c, d, e, f, g, h, i, j, k, l, m);
    ...
}
// Example B
MagicClassHolder x;
switch (id)
{
  case 1:
    set x = ClassA;
  case 2:
    set x = ClassB;
  case 3:
    set x = ClassC;
  case 4:
    set x = ClassD;
    ...
}
return await Callout<x>(a, b, c, d, e, f, g, h, i, j, k, l, m);

Example A is already running fine in my code. And I gather Example B is not feasible. (Though I'd love to be wrong.) However Example B is easier to read. Are there obvious tricks that would improve on what I have in Example A and make it more readable à la Example B?

Wellspring
  • 1,128
  • 1
  • 10
  • 19
  • `TypeA`, `TypeB`, etc aren't types in your first example. So, the second example is nothing like the first. The second example, you are hoping that `Callout(...);` is somehow feasible, correct? – Andy Feb 14 '21 at 00:56
  • Make a generic function encapsulating most of the calling logic, then call it from the `switch`? – Charlieface Feb 14 '21 at 00:57
  • you could have a dictionary of ...itll return the data type you need...more readible than a switch block – Ctznkane525 Feb 14 '21 at 01:00
  • I may have used the wrong words, but the code is true to what I am trying to do. I'll take a swing at fixing my nomenclature. And yes, I tried something along the lines of that... I tried Callout and of course it didn't work. – Wellspring Feb 14 '21 at 01:01
  • Unfortunately I'm already producing a large List<> of the callout type, so I am thinking I would be back in the same problem later after I tried to push a type from a dictionary into <> and ... guessing that wouldn't work. – Wellspring Feb 14 '21 at 01:03
  • Pass the type to the method as argiment of type `Type` instead of generic, change the method signature. – aepot Feb 14 '21 at 01:08
  • Why can't you simply make all of these classes descend from an ancestor? – Loren Pechtel Feb 14 '21 at 01:36
  • Loren, because each class's own distinctions are needed -- even if they were descended from a common ancestor. I'm generating datasets based upon each class's properties--all of them. – Wellspring Feb 14 '21 at 01:38

1 Answers1

1

Generics are a compile time construct. So you cannot do something like in B. However you can use reflection to construct an instance of a generic method which takes x as a parameter and then call it.

https://learn.microsoft.com/en-us/dotnet/api/system.reflection.methodinfo.makegenericmethod?redirectedfrom=MSDN&view=net-5.0#System_Reflection_MethodInfo_MakeGenericMethod_System_Type___


So something like

// Example B
MagicClassHolder x;
switch (id)
{
  case 1:
    set x = ClassA;
  case 2:
    set x = ClassB;
  case 3:
    set x = ClassC;
  case 4:
    set x = ClassD;
    ...
}
return await MakeAndCallout(x, a, b, c, d, e, f, g, h, i, j, k, l, m);
public async Task MakeAndCallout(x, a, b, c, d, e, f, g, h, i, j, k, l, m)
{
     // use MakeGenericMethod to get a (generic) method for type x
     // use MethodInfo from above and an instance of the class to call it with a...m
}
potatopeelings
  • 40,709
  • 7
  • 95
  • 119
  • This looks promising! Thank you! I will dig in on this. BTW did you mean to say, "... *cannot* do something like in B..."? Your wording is a bit confusing there. – Wellspring Feb 14 '21 at 01:13
  • @Wellspring you're right. that's what i meant! fixed! btw i was just searching and found this too - https://stackoverflow.com/questions/232535/how-do-i-use-reflection-to-call-a-generic-method – potatopeelings Feb 14 '21 at 01:20
  • leave it to Jon Skeet to have answered it 10 years ago. More like 15. Which proves I still have room to grow in knowing how to word my questions, or I'd have found this. Thx again! – Wellspring Feb 14 '21 at 01:40