2

I have a block of code like this: (MyClassX is just a shorthand for my business objects, which might extend later ...

var conn = new SQLiteAsyncConnection(dbPath);

conn.CreateTableAsync<MyClass1>().Wait();
conn.CreateTableAsync<MyClass2>().Wait();
conn.CreateTableAsync<MyClass3>().Wait();
conn.CreateTableAsync<MyClass4>().Wait();
conn.CreateTableAsync<MyClass5>().Wait();
...
conn.CreateTableAsync<MyClass20>().Wait();

And would like to somehow refactor it to avoid the repetitiveness and make it more maintainable. One try was something akin to

 // Generic Lambda invocation 
 Action<Type> init_bo = t => conn.GetType().GetMethod("CreateTableAsync")
                             .MakeGenericMethod(t).Invoke(conn, null);
 List<Type> bo_types = new List<Type>() { typeof(MyClass1), typeof(MyClass2), 
                                          ..., typeof(MyClass20) };
 bo_types.ForEach(init_bo);

, which seems not terribly expressive (and does not call Wait()). How could I go about utilizing templates/functional programming to get more expressive and concise code?

Edit: Not a duplicate in my opinion, since I already answered how to call a generic method in the original question, but I was not happy with the resulting code w.r.t. expressiveness.

Hottemax
  • 305
  • 1
  • 12
  • 1
    Good question but on a sidenote.. Why are you using .Wait on an async function? That should be avoided whenever possible as it defeats the purpose of async. – Joelius May 28 '19 at 10:47
  • What is so wrong with what you did? just put the "non-expressive" code in a function with an "expressive" name, and all is done, no? – Ofir Winegarten May 28 '19 at 10:59
  • Possible duplicate of [How do I use reflection to call a generic method?](https://stackoverflow.com/questions/232535/how-do-i-use-reflection-to-call-a-generic-method) – thehennyy May 28 '19 at 11:13
  • @Joelius You are correct, I didn't write this code initially, so I just started the refactoring - I was still stuck on syntax instead of semantics :D – Hottemax May 28 '19 at 14:43

1 Answers1

1

You can call Wait by casting the result to a Task:

var createMethod = conn.GetType().GetMethod("CreateTableAsync");
Task[] createTasks = bo_types.Select(t => (Task)createMethod.MakeGenericMethod(t).Invoke(conn, null)).ToArray();
Tasks.WaitAll(createTasks);
Lee
  • 142,018
  • 20
  • 234
  • 287