将字符串映射到实体以便与泛型方法

时间:2015-07-13 07:56:32

标签: c# generics nhibernate

如果我有以下课程:

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

我有方法:

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

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

}

是否可以使用字典将字符串映射到可以传递给此泛型方法的类型,以便查询右表?

例如:

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

var myType = typeMapper["Apple"];
List<Fruit> fruitList = getFruit<myType>();

3 个答案:

答案 0 :(得分:3)

您可以使用反射来调用带有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>();
}

答案 1 :(得分:3)

如何使用Dictionary存储委托?

    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"]();

答案 2 :(得分:0)

您可以使用Reflection创建未知类型的实例。这可以使用Activator.CreateInstance(typeof(Apple))来完成。 话虽如此,你根本不需要泛型:

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

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

编辑:但是这种方法不是类型安全的,所以你得到的只是object而不是你的具体类型。您可以将结果转换为Fruit,然后将其添加到列表中:

fruitList.Add((Fruit) apple);