Generics 如何获得构造泛型类型的列表?

Generics 如何获得构造泛型类型的列表?,generics,reflection,xna,Generics,Reflection,Xna,我正在进行一个项目(使用Xna),该项目基本上读取XML内容文件以创建处理各种类型输入事件的事件处理程序。XML文件如下所示: <InputMapping> <InputType>Microsoft.Xna.Framework.Input.Keys, Microsoft.Xna.Framework, Version=3.1.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d</InputType>

我正在进行一个项目(使用Xna),该项目基本上读取XML内容文件以创建处理各种类型输入事件的事件处理程序。XML文件如下所示:

<InputMapping>
  <InputType>Microsoft.Xna.Framework.Input.Keys, Microsoft.Xna.Framework, Version=3.1.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d</InputType>
  <Combination>Up W</Combination>
  <CombinationType>Any</CombinationType>
  <Handlers>
    <Handler>MoveUp</Handler>
    <Handler>ScrollMenuUp</Handler>
  </Handlers>
</InputMapping>
public delegate void InputHandler<T>(T input, GameTime gameTime) where T : struct;
[MyInputHandlerAttribute]//This tells my XML-loading method to look in this class for event handler candidates
public static class InputHandlers<T>
    where T : struct
{
    public static void HandleInput<T>(T input, GameTime gameTime)
    {
        /*
        * An input event would be handled here.
        * The type of input event handled would depend entirely on the assembly-qualified
        * name provided in the "<InputType>" element of the XML file.
        * This kind of non-specific input handling might not make sense, but it has its worthwhile uses:
        * serializing input for network transmission
        * (using some interface that T would be constrained to implement) is the use I have in mind.
        */
    }
}

Microsoft.Xna.Framework.Input.Keys,Microsoft.Xna.Framework,版本=3.1.0.0,区域性=中性,PublicKeyToken=6d5c3888ef60e27d
向上W
任何
上移
滚动菜单
“MoveUp”和“ScrollMenuUp”是两个方法的名称,我希望它们能够处理在按下“Up”和/或“W”键时引发的事件,我已经用自定义属性标记了它们的包含类。生成的“输入地图”被添加到游戏中每帧更新的输入地图列表中。当满足输入组合(可能是鼠标按钮单击、滚轮移动、鼠标移动等,具体取决于输入映射的类型)时,将引发一个事件,并使用XML文件中列出的方法进行处理


为了找到XML文件引用的方法,我的计划最初是使用反射在执行程序集中迭代导出的类型,找到应用了我的自定义属性的静态类,并将所有与相关事件的委托签名匹配的公共静态方法存储在字典中,由其名称键入,以供引用相同方法的后续输入映射加载使用。对于发布版本,我将把这个方法列表写到一个文件中,以大大减少加载时间,但是对于调试,我希望这个可用事件处理程序列表与我的修订保持最新

这项工作非常完美,而且比我预期的花费的时间少得惊人。但是,我不知道如何扩展此方法以包括泛型委托:我有一个名为
InputHandler
的泛型委托,看起来如下所示:

<InputMapping>
  <InputType>Microsoft.Xna.Framework.Input.Keys, Microsoft.Xna.Framework, Version=3.1.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d</InputType>
  <Combination>Up W</Combination>
  <CombinationType>Any</CombinationType>
  <Handlers>
    <Handler>MoveUp</Handler>
    <Handler>ScrollMenuUp</Handler>
  </Handlers>
</InputMapping>
public delegate void InputHandler<T>(T input, GameTime gameTime) where T : struct;
[MyInputHandlerAttribute]//This tells my XML-loading method to look in this class for event handler candidates
public static class InputHandlers<T>
    where T : struct
{
    public static void HandleInput<T>(T input, GameTime gameTime)
    {
        /*
        * An input event would be handled here.
        * The type of input event handled would depend entirely on the assembly-qualified
        * name provided in the "<InputType>" element of the XML file.
        * This kind of non-specific input handling might not make sense, but it has its worthwhile uses:
        * serializing input for network transmission
        * (using some interface that T would be constrained to implement) is the use I have in mind.
        */
    }
}
public-delegate-void-InputHandler(T-input,GameTime-GameTime),其中T:struct;
我可以很好地获取委托的签名,但我的问题是,我不知道如何获取由泛型类型构造的类,这些泛型类型包含可由
InputHandler
表示的方法。更简单地说,我有一个名为
InputHandlers
的类,它如下所示:

<InputMapping>
  <InputType>Microsoft.Xna.Framework.Input.Keys, Microsoft.Xna.Framework, Version=3.1.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d</InputType>
  <Combination>Up W</Combination>
  <CombinationType>Any</CombinationType>
  <Handlers>
    <Handler>MoveUp</Handler>
    <Handler>ScrollMenuUp</Handler>
  </Handlers>
</InputMapping>
public delegate void InputHandler<T>(T input, GameTime gameTime) where T : struct;
[MyInputHandlerAttribute]//This tells my XML-loading method to look in this class for event handler candidates
public static class InputHandlers<T>
    where T : struct
{
    public static void HandleInput<T>(T input, GameTime gameTime)
    {
        /*
        * An input event would be handled here.
        * The type of input event handled would depend entirely on the assembly-qualified
        * name provided in the "<InputType>" element of the XML file.
        * This kind of non-specific input handling might not make sense, but it has its worthwhile uses:
        * serializing input for network transmission
        * (using some interface that T would be constrained to implement) is the use I have in mind.
        */
    }
}
[MyInputHandlerAttribute]//这告诉我的XML加载方法在这个类中查找候选事件处理程序
authandler中的公共静态类
其中T:struct
{
公共静态无效句柄输入(T输入,游戏时间游戏时间)
{
/*
*这里将处理一个输入事件。
*处理的输入事件的类型将完全取决于程序集
*XML文件的“”元素中提供的名称。
*这种非特定的输入处理可能没有意义,但它有其值得使用的地方:
*网络传输的串行输入
*(使用一些T必须实现的接口)是我想到的用途。
*/
}
}
我希望能够在XML文件中简单地键入
HandleInput
,并找到MethodInfo,该MethodInfo与从
InputHandlers
构造的类中定义的方法相对应,其泛型参数与我要处理的事件相对应(与事件的
InputHandler
声明中使用的T类型相同,我只能从XML文件中列出的程序集限定名中导出该事件)


我知道(从C#规范中)在运行时不存在开放类型,因此如何获得从泛型类构造的封闭类型列表?

如果我理解正确,您需要根据XML文件中指定的字符串值调用泛型方法。这将实现以下目的:

void Main() {
    HandleEvent ("WindowsBase", "System.Windows.Input.Key");
    // I dont have XNA, so I could not test your specific classes
    // HandleEvent ("Microsoft.Xna.Framework",  "Microsoft.Xna.Framework.Input.Keys"); 
}

void HandleEvent(string assemblyName, string typeName)
{   
    var instance = Assembly.Load(assemblyName).CreateInstance(typeName);
    Handler.Handle(instance);
}

static class Handler {
    public static void Handle<T>(T input)  {
        Console.WriteLine("Handling input of type: " + input.GetType());
    }
}
void Main(){
HandleEvent(“WindowsBase”、“System.Windows.Input.Key”);
//我没有XNA,所以我无法测试您的特定类
//HandleEvent(“Microsoft.Xna.Framework”、“Microsoft.Xna.Framework.Input.Keys”);
}
void HandleEvent(字符串assemblyName、字符串typeName)
{   
var instance=Assembly.Load(assemblyName).CreateInstance(typeName);
Handle.Handle(实例);
}
静态类处理程序{
公共静态无效句柄(T输入){
WriteLine(“处理类型为:+input.GetType()的输入”);
}
}

您可能需要添加错误处理、空检查等。

事实证明,我过于复杂化了这个问题。我真正的问题是,尽管我不知道,但如何获得泛型类型定义(即
typeof(inputhandler)
,没有特定的泛型参数)仅使用类型的名称。这很简单:

Type genericDefinition = typeof(<some type in my assembly>).Assembly.GetTypes().Where(t=>(t.IsGenericDefinition && t.Name == <the name I'm looking for>)).First();

Type genericDefinition=typeof().Assembly.GetTypes().Where(t=>(t.IsGenericDefinition&&t.Name==谢谢,但这不是我需要的…我需要一种方法来获取System.Reflection.MethodInfo对象,该对象表示从泛型“InputHandler”类构造的运行时类型中泛型方法“HandleInput”的定义。另外,传递“instance”(属于object类型)to Handler.Handle某种程度上避免了在方法中使用泛型参数-'T'将始终是System.Object。这几乎阻止了该类型的任何有用的反射。我也在想这是否有用……但是,input.GetType()确实得到了具体的类型,在本例中,您得到了输出“处理类型为:System.Windows.input.Key的输入”是的,你是对的-我的错误。GetType()方法和传递给方法(如示例中的方法)的隐式参数都将获得任何对象的具体类型。