C#使用类型为的泛型方法

C#使用类型为的泛型方法,c#,generics,reflection,C#,Generics,Reflection,我正在使用.Net framework 2.0尝试执行以下操作: 我有一个外部服务,它返回一个int列表。反过来,我使用每个int查找一个对应的类型,该类型有一个属性key;该属性的值与搜索参数匹配 使用类型t我想调用一个泛型方法,但我不能这样做。由于我只知道运行时的类型,我怀疑我可能必须使用反射来调用泛型方法GetResultsForType-这是正确的方法吗 [MyAttribute(key1 = 1)] class A{ //some properties } [MyAttrib

我正在使用.Net framework 2.0尝试执行以下操作:

我有一个外部服务,它返回一个int列表。反过来,我使用每个int查找一个对应的类型,该类型有一个属性key;该属性的值与搜索参数匹配

使用类型
t
我想调用一个泛型方法,但我不能这样做。由于我只知道运行时的类型,我怀疑我可能必须使用反射来调用泛型方法
GetResultsForType
-这是正确的方法吗

[MyAttribute(key1 = 1)]
class A{
    //some properties
}

[MyAttribute(key1 = 2)]
class B{
    //some properties
}

//and so on (for hundreds of classes).  The key is unique for every class.

public class Foo{
    public void DoSomething(){
         IList<int> keys = QuerySomeExternalService();

         Assembly asm = LoadAssemblyFromSomewhere();
         Type[] types = asm.GetTypes();
         foreach(int key in keys){
             Type t = SearchTypesForAttributeWithMatchingKey(types, key);  //I omitted caching of all the keys and Types into a Dictionary on first iteration for brevity.
             IList<t> results = GetResultsForType<t>(); //won't work!
             //do something with the results
         }
    }

    Type SearchTypesForAttributeWithMatchingKey(Type[] types, int key){
        foreach(Type t in types){
            object[] attributes = t.GetCustomAttributes(typeof(MyAttribute),false);
            MyAttribute myAtt = attributes[0] as MyAttribute;
            if(myAtt.Key == key) return t;
        }
    }

    IList<T> GetResultsForType<T>(){
        IList<T> results = new List<T>();
        bool querySuccess = true;
        while(querySuccess){
            T result;
            querySuccess = QueryExternalService<T>(out result);
            results.Add(result);
        }
        return results;
    }
}
[MyAttribute(key1=1)]
甲级{
//一些性质
}
[MyAttribute(键1=2)]
B类{
//一些性质
}
//等等(上百节课)。每个类的键都是唯一的。
公开课Foo{
公共无效剂量测定法(){
IList keys=QuerySomeExternalService();
Assembly asm=LoadAssemblyFromwhere();
Type[]types=asm.GetTypes();
foreach(int键入键){
Type t=searchtypesforattributewthmatchingkey(types,key);//为了简洁起见,我在第一次迭代时省略了将所有键和类型缓存到字典中。
IList results=GetResultsForType();//不起作用!
//对结果做点什么
}
}
键入SearchTypesFrattributeWithMatchingKey(键入[]类型,int键){
foreach(类型中的类型t){
object[]attributes=t.GetCustomAttributes(typeof(MyAttribute),false);
MyAttribute myAtt=属性[0]作为MyAttribute;
if(myAtt.Key==Key)返回t;
}
}
IList GetResultsForType(){
IList results=新列表();
bool querySuccess=true;
while(querySuccess){
T结果;
querySuccess=QueryExternalService(输出结果);
结果。添加(结果);
}
返回结果;
}
}

是的,您必须使用反射来使用
系统调用泛型方法。键入
而不是泛型参数化。找到泛型方法后,可以在methodInfo
MakeGenericMethod(params Type[])
上使用该方法

如果您知道该方法经常被调用,但类型很少,那么可以缓存委托以调用正确的版本

比如::

typeof(Foo).GetMethod("YourMethod").MakeGenericMethod(type).Invoke(new[]{parameters});

是的,您必须使用反射来调用泛型方法,使用
System.Type
而不是泛型参数化。找到泛型方法后,可以在methodInfo
MakeGenericMethod(params Type[])
上使用该方法

如果您知道该方法经常被调用,但类型很少,那么可以缓存委托以调用正确的版本

比如::

typeof(Foo).GetMethod("YourMethod").MakeGenericMethod(type).Invoke(new[]{parameters});

这与上一个问题()非常相似,在这里您使用
System.Type
的实例来代替Type param来调用泛型方法。我知道你并没有真正征求架构方面的建议,但如果你不得不左右对抗类型系统,这表明你的设计有问题。我个人很想知道您在这里实际要解决的问题是什么,而不是如何解决的,也许有人可以建议一种更简洁的方法。这与您的上一个问题()非常相似,您使用
System.Type
的实例来代替Type param来调用泛型方法。我知道你并没有真正征求架构方面的建议,但如果你不得不左右对抗类型系统,这表明你的设计有问题。我个人很想知道你到底想解决什么样的问题,而不是如何解决,也许有人可以建议一种更干净的方法。