首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在.NET中使用GetMethod区分泛型和非泛型签名?

如何在.NET中使用GetMethod区分泛型和非泛型签名?
EN

Stack Overflow用户
提问于 2012-07-20 01:56:55
回答 2查看 4.8K关注 0票数 24

假设存在如下所述的类X,我如何获取非泛型方法的方法信息?下面的代码将抛出一个异常。

代码语言:javascript
复制
using System;

class Program {
    static void Main(string[] args) {
        var mi = Type.GetType("X").GetMethod("Y"); // Ambiguous match found.
        Console.WriteLine(mi.ToString());
    }
}

class X {
    public void Y() {
        Console.WriteLine("I want this one");
    }
    public void Y<T>() {
        Console.WriteLine("Not this one");
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-20 02:00:26

不要使用GetMethod,使用GetMethods,然后检查IsGenericMethod

代码语言:javascript
复制
using System;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        var mi = Type.GetType("X").GetMethods().Where(method => method.Name == "Y"); 
        Console.WriteLine(mi.First().Name + " generic? " + mi.First().IsGenericMethod);
        Console.WriteLine(mi.Last().Name + " generic? " + mi.Last().IsGenericMethod);
    }
}

class X
{
    public void Y()
    {
        Console.WriteLine("I want this one");
    }
    public void Y<T>()
    {
        Console.WriteLine("Not this one");
    }
}

作为一个额外的好处-一种扩展方法:

代码语言:javascript
复制
public static class TypeExtensions
{
    public static MethodInfo GetMethod(this Type type, string name, bool generic)
    {
        if (type == null)
        {
            throw new ArgumentNullException("type");
        }
        if (String.IsNullOrEmpty(name))
        {
            throw new ArgumentNullException("name");
        }
        return type.GetMethods()
            .FirstOrDefault(method => method.Name == name & method.IsGenericMethod == generic);
    }
}

然后只需:

代码语言:javascript
复制
static void Main(string[] args)
{
    MethodInfo generic = Type.GetType("X").GetMethod("Y", true);
    MethodInfo nonGeneric = Type.GetType("X").GetMethod("Y", false);
}
票数 33
EN

Stack Overflow用户

发布于 2019-03-13 20:32:04

基于Konrad Morawski的回答,我创建了一个增强的扩展方法:

代码语言:javascript
复制
public static MethodInfo GetMethod (this Type i_oContainingType,
                                         string i_sMethodName,
                                         BindingFlags i_enBindingFlags,
                                         Type[] i_aoArgumentType,
                                         bool i_bGeneric)
{
  if (i_oContainingType == null)
    throw new ArgumentNullException (nameof (i_oContainingType));

  var aoMethod = i_oContainingType.GetMethods (i_enBindingFlags);
  var listoMethod = new List<MethodInfo> ();
  foreach (var oMethod in aoMethod)
  {
    if (!string.Equals (oMethod.Name, i_sMethodName))
      continue;
    if (oMethod.IsGenericMethod != i_bGeneric)
      continue;
    var aoParameter = oMethod.GetParameters ();
    if (aoParameter.Length != i_aoArgumentType?.Length)
      continue;
    int iParamMatch = 0;
    for (int ixParam = 0; ixParam < aoParameter.Length; ixParam++)
    {
      if (aoParameter[ixParam].ParameterType == i_aoArgumentType[ixParam])
        iParamMatch++;
    }
    if (iParamMatch != aoParameter.Length)
      continue;
    listoMethod.Add (oMethod);
  }
  if (listoMethod.Count != 1)
  {
    string sError = "Method with Name '" + i_sMethodName + "' and BindingFlags '" + i_enBindingFlags + "' and Parameter Types '" + i_aoArgumentType?.ToString ("', '") + "'";
    if (listoMethod.Count == 0)
      throw new MissingMethodException (sError + " has no match.");
    else
      throw new AmbiguousMatchException (sError + " has " + listoMethod.Count + " matches.");
  }
  return listoMethod[0];
}

public static MethodInfo GetPrivateInstanceMethod (this Type i_oContainingType,
                                                        string i_sMethodName,
                                                        Type[] i_aoArgumentType,
                                                        bool i_bGeneric)
{
  return GetMethod (i_oContainingType, i_sMethodName, BindingFlags.NonPublic | BindingFlags.Instance, i_aoArgumentType, i_bGeneric);
}

public static MethodInfo GetPublicInstanceMethod (this Type i_oContainingType,
                                                       string i_sMethodName,
                                                       Type[] i_aoArgumentType,
                                                       bool i_bGeneric)
{
  return GetMethod (i_oContainingType, i_sMethodName, BindingFlags.Public | BindingFlags.Instance, i_aoArgumentType, i_bGeneric);
}

注意:

i_aoArgumentType.ToString (..)是另一种扩展方法。我想你可以猜到它是做什么用的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11566613

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档