我正在尝试通过反射找到界面授予我的所有方法。我有一个类型数组,我验证只有接口,从那里我需要提取所有方法。不幸的是,如果我做类似typeof(IList).GetMethods()它只返回IList上的方法而不是ICollection上的方法,或者IEnumerable的 我已经尝试了以下linq查询,但它不返回外部接口上找到的方法。如何修复查询?
from outerInterfaces in interfaces
from i in outerInterfaces.GetInterfaces()
from m in i.GetMethods()
select m
如果这是SQL,我可以做一些类似于带有union all的递归CTE,但我不认为C#中存在这样的语法。任何人都可以帮忙吗?
答案 0 :(得分:6)
这样的事情怎么样:
typeof(IList<>).GetMethods().Concat(typeof(IList<>)
.GetInterfaces()
.SelectMany(i => i.GetMethods()))
.Select(m => m.Name)
.ToList().ForEach(Console.WriteLine);
编辑:回复评论。
使用以下代码进行测试:
public interface IFirst
{
void First();
}
public interface ISecond : IFirst
{
void Second();
}
public interface IThird :ISecond
{
void Third();
}
public interface IFourth : IThird
{
void Fourth();
}
测试代码:
typeof(IFourth).GetMethods().Concat(typeof(IFourth)
.GetInterfaces()
.SelectMany(i => i.GetMethods()))
.Select(m => m.Name)
.ToList().ForEach(Console.WriteLine);
输出是:
Fourth
Third
Second
First
答案 1 :(得分:4)
没有“内置”LINQ递归(我知道),但您可以创建一个样板LINQ扩展来获取所有后代:(警告:在记事本中编译)
static public class RecursionExtensions
{
static public IEnumerable<T> AllDescendants<T>(this IEnumerable<T> source,
Func<T, IEnumerable<T>> descender)
{
foreach (T value in source)
{
yield return value;
foreach (T child in descender(value).AllDescendants<T>(descender))
{
yield return child;
}
}
}
}
然后您可以像这样使用它,将基类型视为树中的后代节点:
from ifaceType in interfaces.AllDescendants( t => t.GetInterfaces())
鉴于您可以撰写方法选择器:
from ifaceType in interfaces.AllDescendants( t=> t.GetInterfaces())
from m in ifaceType.GetMethods()
select m
它应该为您提供interfaces
集合中所有接口的所有方法,以及所有基本接口