C#反射,获取重载方法
C# reflection, get overloaded method
我已经检查了一些关于反射和重载方法的其他 post,但可以找到任何帮助。我找到的一个 post 是 this one,但这并没有多大帮助。
我有以下两种方法:
1 | public void Delete<T>(T obj) where T : class { ... }
2 | public void Delete<T>(ICollection<T> obj) where T : class { ... }
我正在尝试获取方法 N°1。
我尝试了经典的 GetMethod("Delete")
方法,但由于有两个方法具有此名称,因此抛出了 Ambiguous
-Exception。我尝试使用 GetMethod("Delete", new [] { typeof(Object) })
等附加参数指定方法架构,但没有找到任何内容(空 returned)。
我想我也可以循环遍历所有方法并检查参数。
我写了下面的方法...
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();
}
...其中 returns 不包含类型为 schemaExclude
的参数的方法。
我是这样称呼它的
GetMethods("Delete", typeof(ICollection))
没有按预期工作。
显然 ..ICollection'1[T]
不能分配给 ICollection
。 IEnumerable
、IEnumerable<>
和 ICollection<>
也不是。我再次使用 typeof(Object)
进行了尝试,它确实有效,但是 return 两种方法(就像它应该的那样)。
我到底错过了什么?
您可以通过检查其泛型参数类型来查找该方法,如下所示:
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;
符合以下条件的上述筛选方法:
- 叫 'Delete',
- 只有一个参数,
- 参数为泛型,
- 使用从
ICollection<>
构造的泛型参数类型
我已经检查了一些关于反射和重载方法的其他 post,但可以找到任何帮助。我找到的一个 post 是 this one,但这并没有多大帮助。
我有以下两种方法:
1 | public void Delete<T>(T obj) where T : class { ... }
2 | public void Delete<T>(ICollection<T> obj) where T : class { ... }
我正在尝试获取方法 N°1。
我尝试了经典的 GetMethod("Delete")
方法,但由于有两个方法具有此名称,因此抛出了 Ambiguous
-Exception。我尝试使用 GetMethod("Delete", new [] { typeof(Object) })
等附加参数指定方法架构,但没有找到任何内容(空 returned)。
我想我也可以循环遍历所有方法并检查参数。
我写了下面的方法...
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();
}
...其中 returns 不包含类型为 schemaExclude
的参数的方法。
我是这样称呼它的
GetMethods("Delete", typeof(ICollection))
没有按预期工作。
显然 ..ICollection'1[T]
不能分配给 ICollection
。 IEnumerable
、IEnumerable<>
和 ICollection<>
也不是。我再次使用 typeof(Object)
进行了尝试,它确实有效,但是 return 两种方法(就像它应该的那样)。
我到底错过了什么?
您可以通过检查其泛型参数类型来查找该方法,如下所示:
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;
符合以下条件的上述筛选方法:
- 叫 'Delete',
- 只有一个参数,
- 参数为泛型,
- 使用从
ICollection<>
构造的泛型参数类型