0

I'm working on a project that imports Data from csv/xml files and stores the chosen data in a SQL-database. I encountered a problem where I had to call certain generic methods with type parameters which are dependent and I don't want to code each possible case.

Is there a way to pass type parameter in a variable fashion?

I already solved the problem in a hacky way. I'm just curious if there is a recommended way since this is common scenario.

EDIT: My approach looks something like this:

I have generated a Func<dynamic> that returns a new instance of a certain entity and stored them all in Dictionary along with the name of the entity.

Every generic method that I want to call in the mentioned way, got a parameter of the generic type. This way the compiler can figure out the type without the need of writing it explicitly. The only drawback is that I have to pass a dummy each time.

public abstract class Entity
{
    private static readonly Dictionary<string, Func<dynamic>> instantiateNewTypedEntityDelegatesDict;

    static Entity()
    {
        Assembly assembly = Assembly.GetExecutingAssembly();
        instantiateNewTypedEntityDelegatesDict = new Dictionary<string, Func<dynamic>>();
        foreach (var entityType in assembly.GetTypes().Where(x => x.IsSubclassOf(typeof(Entity))))
        {
            CreateInstantiateNewTypedEntityDelegate(entityType);
        }
    }

    private static void CreateInstantiateNewTypedEntityDelegate(Type entityType)
    {
        NewExpression newExpr = Expression.New(entityType.GetConstructor(new Type[0]) ?? throw new InvalidOperationException());
        instantiateNewTypedEntityDelegatesDict.Add(entityType.Name, Expression.Lambda<Func<dynamic>>(newExpr).Compile());
    }

    public static dynamic CreateNewTypedEntity(string entityName)
    {
        return instantiateNewTypedEntityDelegatesDict[entityName]();
    }
}

And a sample prototype of a method I want to call:

public TEntity GenericMethodIWantToCall<TEntity>(TEntity dummyEntity /*other paramters do not matter*/)
Felix Lechenbauer
  • 140
  • 1
  • 3
  • 9
  • 3
    Show the "hacky" way. – Equalsk Jan 02 '18 at 16:31
  • Passing type parameters can be done by the type `Type` or by templated function/classes. More details please - you might not need that at all. – Patrick Artner Jan 02 '18 at 16:40
  • You can pass a type as a parameter. `void PassMeAType(Type type)`; – Scott Hannen Jan 02 '18 at 16:40
  • `My approach looks something like this` - Ideally you should [create a Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve) rather than give a vague outline, then I suspect you'll get a proper answer very quickly. – Equalsk Jan 02 '18 at 16:46
  • It is important that the type parameter is a generic because of the return type and other method calls which also require the generic form. – Felix Lechenbauer Jan 02 '18 at 16:49
  • Based on the above, it appears that the dictionary is simply there so you can create the "dummy" object mentioned here: _"The only drawback is that I have to pass a dummy each time"_. Which _is_ very hacky, and not at all the right way to do this. See marked duplicate for how to call a generic method when the type is known only at runtime. Note also that most people who get into this situation, they shouldn't have and there's usually a better way to solve their problem. But if you decide you _must_ abandon compile-time type safety, the duplicate will show you how. – Peter Duniho Jan 02 '18 at 20:21
  • In this case the setup around the dictionary serves to create a dummy object, but there are other use cases in my solution as well. ... I saw your marked question, but I hoped for a faster way to solve this. ... I could expand on why I need this and the idea behind if its appropriate here. Or should I open another question for that? – Felix Lechenbauer Jan 02 '18 at 20:43

0 Answers0