0

I have a custom class Customer and inside another class a method that returns a list based on a LiteCollection from LiteDB typized using the Customer class in the signature. What I wanted to know is if it’s possible creating a method that dynamically chooses which class uses a type, meaning if I can pass as a parameter the class type of the LiteCollection to return when I call the method.

The code is as follows:

public static LiteCollection<Customer> GetCustomers()
        {
            var collection = ConnectToDB().GetCollection<Customer>("customers");

            return collection;
        }
nicktheone
  • 77
  • 2
  • 10
  • 2
    What do you mean "dynamically"? Why not make your method itself generic, just like `GetCollection<>` eg `GetWhatevers(string name)=>ConnectoToDB().GetCollection(name)` ? Or could pass `dynamic` as the type parameter, although you'd *still* have to know what members to call. If you do, why not specify the class directly? – Panagiotis Kanavos Nov 29 '18 at 08:05
  • As I commented on @Oliver answer when I choose what kind of list my method returns (`LiteCollection` in my case) it explicitly asks a class instead of a generic `` and that parameter is what I'd like to be able to somehow pass as to be able to have a single method accepting `Customers` or `Whatever` as a class. – nicktheone Nov 29 '18 at 16:01
  • `T` *is* the type parameter. It's even called a `type parameter`. You don't need multiple methods - if you know what type you want, just pass it as the type parameter. If you don't want to specify a type though , pass `dynamic` as the type, assuming `LiteDB` allows this. – Panagiotis Kanavos Nov 29 '18 at 16:09
  • @nicktheone: does it say that T must be a class? If so just use a generic type constraint that says your T must be a class and it should then work. See https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/where-generic-type-constraint for more info. – Chris Nov 29 '18 at 16:09
  • @Panagiotis Kanavos in my method signature it says "the type or namespace name T could not be found". – nicktheone Nov 29 '18 at 16:43
  • @nicktheone where is that signature? Post your code. Oliver already showed how easy it is to specify the type. That code works. Don't force people to guess what you did or what you actually want – Panagiotis Kanavos Nov 30 '18 at 07:36

1 Answers1

2

How about:

public static LiteCollection<T> Get(string tableName)
{
    return ConnectToDB().GetCollection<T>(tableName);
}

That would be called:

var table = Get<Customer>("customers");

Update

Unfortunately it is not really possible to get rid of the generic type, cause otherwise your consuming code doesn't know what it gets back. So the minimum that would be possible would be

var table = Get<Customer>();

In that case your implementation needs some kind of mapper from type to table name. For this purpose I could think of three possibilities (which you could also combine):

  • The class has an internal Dictionary<Type, string> where all table names for a given type is manually entered.
  • The convention is that for every T the table name is a pluralized string of the type name, then you need a pluralize method that returns Pluralize(typeof(T).Name).
  • By reflection you iterate over your derived DBContext, get out all DBSet<> properties and pre-fill the dictionary out of the first possibility by using the generic argument from DBSet<> and the property name.
Oliver
  • 43,366
  • 8
  • 94
  • 151
  • I tried but it explicitly asks me for a class as a parameter (Customers in my case) when choosing what kind of collection is returned. My issue it's not how to dynamically choose from which table to retrieve data but which class should be used as a stron type (). Ideally it's because I don't want to have several methods all referencing only a single class. – nicktheone Nov 29 '18 at 15:56