1

if I have the following classes:

class Fruit {}
class Apple : Fruit {}
class Orange : Fruit {}

and I have method:

public List<Fruit> getFruit<T>() where T : Fruit {

 List<Fruit> fruitList = new List<Fruit>();
 return fruitList.AddRange(session.QueryOver<T>().List());

}

Is it possible to have a dictionary that maps a string to a type that can be passed to this generic method so I can query over the right table?

for example:

Dictionary<string, type> typeMapper = new Dictionary<string, type>()
{
 {"Apple", AppleType??}
};

var myType = typeMapper["Apple"];
List<Fruit> fruitList = getFruit<myType>();
1
  • generic types in c# must be known at compile time. You can't use <typeof(mytype)> because it's not a compiler time operation. From MSDN.com - "The type argument can be any type recognized by the compiler."... (and it's not recognized if you use run-time operation) Commented Jul 13, 2015 at 8:04

3 Answers 3

4

How about using Dictionary to store delegates ?

    Dictionary<string, Func<List<Fruit>>> typeMapper = new Dictionary<string, Func<List<Fruit>>>()
    {
        {"Apple", () => { return getFruit<Apple>(); } },
        {"Orange", () => { return getFruit<Orange>(); } }
    };

    List<Fruit> fruitList = typeMapper["Apple"]();
Sign up to request clarification or add additional context in comments.

1 Comment

This is the answer I've been waiting for!
3

You can use reflection to call a generic method with a Type

[Fact]
public void Test_WithTypesAndReflection_Succeeds()
{
    var typeMapper = new Dictionary<string, Type>()
    {
        { "Apple", typeof(Apple) },
        { "Orange", typeof(Orange) }
    };

    var method = (
        from m in this.GetType().GetMethods(BindingFlags.Instance | BindingFlags.NonPublic)
        where m.Name == "GetFruit"
        where m.GetParameters().Count() == 0
        select m).Single();

    var result = (IEnumerable<Fruit>)method
        .MakeGenericMethod(typeMapper["Apple"])
        .Invoke(this, null);
}

private IEnumerable<Fruit> GetFruit<T>() where T : Fruit
{
    return Enumerable.Empty<T>().Cast<Fruit>();
}

Comments

0

You can create instances of unknown type using Reflection. This can be done using Activator.CreateInstance(typeof(Apple)) e g. Having said this you won´t need generics at all:

Dictionary<string, Type> typeMapper = new Dictionary<string, Type>()
{
    {"Apple", typeof(Apple)}
};

var myType = typeMapper["Apple"];
var apple = Activator.CreateInstance(myType);

EDIT: However this method is not typesafe, so all you get is an object instead of your concrete type. You may cast the result to Fruit however and add it to the list:

fruitList.Add((Fruit) apple);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.