如何将“Type”类型的变量传递给泛型参数

时间:2010-02-11 20:39:34

标签: c# generics

我正在尝试这样做:

Type type = Type.GetType(string.Format("Gestor.Data.Entities.{0}, Gestor.Data", e.Item.Value));
MetaDataUtil.GetColumnasGrid<type>();

但它不起作用,你知道我怎么能这样做吗?

2 个答案:

答案 0 :(得分:17)

你需要使用反射。

var method =
    typeof(MetaDataUtil)
    .GetMethod("GetColumnasGrid")
    .MakeGenericMethod(new [] { type })
    .Invoke(null, null);

答案 1 :(得分:3)

如果它是一个实例方法而不是静态方法,那么你将变量传递给Invoke(第二个参数null用于通常传递给方法的参数数组,在null的情况下就像调用没有参数.GetColumnAsGrid())的方法:

Type genericTypeParameter = Type.GetType(string.Format("Gestor.Data.Entities.{0}, Gestor.Data", e.Item.Value));
MetaDataUtil someInstance = new MetaDataUtil();

var returnResult =
    typeof(MetaDataUtil)
    .GetMethod("GetColumnsAsGrid")
    .MakeGenericMethod(new [] { genericTypeParameter })
    .Invoke(someInstance, null);//passing someInstance here because we want to call someInstance.GetColumnsAsGrid<...>()

如果你有不明确的重载异常,可能是因为GetMethod找到了多个具有该名称的方法。在这种情况下,您可以改为使用GetMethods并使用条件过滤到您想要的方法。这可能有点脆弱,因为有人可能会添加另一个类似于你的标准的方法,然后当它返回多个方法时它会破坏你的代码:

var returnResult = 
    typeof(MetaDataUtil)
    .GetMethods().Single( m=> m.Name == "GetColumnsAsGrid" && m.IsGenericMethod 
        && m.GetParameters().Count() == 0 //the overload that takes 0 parameters i.e. SomeMethod()
        && m.GetGenericArguments().Count() == 1 //the overload like SomeMethod<OnlyOneGenericParam>()
    )
    .MakeGenericMethod(new [] { genericTypeParameter })
    .Invoke(someInstance, null);

这并不完美,因为你仍然可能有些含糊不清。我只是检查计数,你真的需要遍历GetParameters和GetGenericArguments并检查每一个以确保它匹配你想要的签名。