【问题标题】:C# Reflection: GetMethods(..) failing to retrieve anythingC# 反射:GetMethods(..) 无法检索任何内容
【发布时间】:2014-01-07 17:01:39
【问题描述】:

我目前正在尝试获得一组非常具体的方法,但未能如愿。 我需要从实现某个接口的所有类中获取与某个签名匹配的所有方法。

到目前为止我得到的是:

IEnumerable<System.Type> classes = Assembly.GetAssembly(typeof(IActionMethod)).GetTypes().Where(x => x.GetInterface("IActionMethod") != null);
MethodInfo[] methods;
List<MethodInfo> relevant;
ParameterInfo[] parameters;
foreach(System.Type cls in classes)
{
    methods = cls.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public);
    relevant.Clear();
    for(int i = 0; i < methods.Length; i++)
    {
        parameters = methods[i].GetParameters();
        if(parameters.Length == 1 && parameters[0].GetType() == typeof(GameObject) && methods[i].ReturnType == typeof(void))
            relevant.Add(methods[i]);
    }
}

此代码在GetMethods(..) 处已失败,未返回任何方法。 我不明白的是,如果它们不实现接口,我可以接收任何相关类的所有公共方法。

接口本身不包含任何东西,我只是用它来“标记”相关的类,因为我想不出任何其他解决方案来做到这一点。

谁能告诉我为什么界面呈现GetMethodsuseless 或者指出我上面代码中的错误?

【问题讨论】:

  • 请给出一个简短但完整的例子。请注意,您在每次迭代时都会完全清除 relevant 列表 - 您确定要这样做吗?

标签: c# reflection interface


【解决方案1】:

顺便说一句,Microsoft recommends 不使用“标记接口”,而是建议使用属性。然后你可以useMemberinfo.IsDefined()而不是检查接口。

【讨论】:

  • 感谢您的提示,我会尽快更改!
【解决方案2】:

要查找所有实现特定接口的类,您应该使用而不是IsAssignableFrom,因为您的代码将省略间接实现您的接口的类:

 Type interfaceType = typeof(IActionMethod);
 Assembly assembly = Assembly.GetAssembly(interfaceType );
 IEnumerable<System.Type> classes = assembly.GetTypes().Where(x => interfaceType.IsAssignableFrom(x));

那么,你可能想调用:

 methods = cls.GetMethods(...)

因为cls 是您想要的类型,您目前正在其Type 中搜索。

【讨论】:

  • 没有类会间接实现接口,但我会记住这一点,如果我无法使用 Wai Ha Lee 建议的属性标记类,我会在以后更改它。
【解决方案3】:

我怀疑这是问题所在:

foreach(System.Type cls in classes)
{    
    methods = cls.GetType().GetMethods(...)

cls 已经是 Type,因此在其上调用 GetType() 将返回 System.Type(或子类)。我怀疑你只是想要:

foreach(System.Type cls in classes)
{    
    methods = cls.GetMethods(...)

还不清楚您为什么要在每次迭代中清除 relevant 列表。这意味着末尾的 only 条目将是您查看的最后一门课程中的条目 - 您确定这是您想要的吗?

【讨论】:

  • 非常感谢,已解决!我想我在再次调用 GetType() 时没有考虑。至于每次迭代清除相关列表:我将方法的名称保存在不同的变量中,并且每个类需要不同的名称数组。我省略了将名称存储在上面的代码中,因为它与我的问题无关。一旦我清除了列表,我就已经从中得到了我想要的东西,并且可以在不丢失任何数据的情况下轻松地做到这一点。再次感谢您的快速而有帮助的回复!
猜你喜欢
  • 2016-03-10
  • 1970-01-01
  • 2015-06-22
  • 2011-05-17
  • 2021-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-11
相关资源
最近更新 更多