C#反射,获取重载方法

Tob*_*rth 5 c# generics reflection overloading generic-list

我已经检查了一些关于反射和重载方法的其他帖子,但可以找到任何帮助。我发现的一篇文章是this one,但这并没有多大帮助。

我有以下两种方法:

1 | public void Delete<T>(T obj) where T : class { ... }
2 | public void Delete<T>(ICollection<T> obj) where T : class { ... }
Run Code Online (Sandbox Code Playgroud)

我正在尝试获取方法 N°1。

我尝试了经典GetMethod("Delete")方法,但由于有两个具有此名称的方法,因此Ambiguous抛出了-Exception。我尝试使用附加参数指定方法架构,例如GetMethod("Delete", new [] { typeof(Object) })没有找到任何东西(返回空值)。

我想我不妨循环遍历所有方法并检查参数。

我写了以下方法...

    public static IEnumerable<MethodInfo> GetMethods(this Type type, String name, Type schemaExclude)
    {
        IEnumerable<MethodInfo> m = type.GetRuntimeMethods().Where(x => x.Name.Equals(name));
        return (from r in m let p = r.GetParameters() where !p.Any(o => schemaExclude.IsAssignableFrom(o.ParameterType)) select r).ToList();
    }
Run Code Online (Sandbox Code Playgroud)

...返回不包含 type 参数的方法schemaExclude

我这样称呼它 GetMethods("Delete", typeof(ICollection)),但没有按预期工作。

显然..ICollection'1[T]不能分配给ICollection. 也不是IEnumerableIEnumerable<>ICollection<>。我再次尝试使用typeof(Object)它确实有效但确实返回了两种方法(就像它应该的那样)。

我到底错过了什么?

das*_*ght 4

您可以通过检查其泛型参数类型来查找该方法,如下所示:

return type
    .GetRuntimeMethods()
    .Where(x => x.Name.Equals("Delete"))
    .Select(m => new {
         Method = m
    ,   Parameters = m.GetParameters()
    })
    .FirstOrDefault(p =>
        p.Parameters.Length == 1
    &&  p.Parameters[0].ParameterType.IsGenericType
    &&  p.Parameters[0].ParameterType.GetGenericTypeDefinition() == typeof(ICollection<>)
    )?.Method;
Run Code Online (Sandbox Code Playgroud)

上述过滤方法符合以下条件:

  • 称为“删除”,
  • 使用单个参数,
  • 由于参数是泛型类型,
  • 使用构造的泛型参数类型ICollection<>

演示。