Get all methods on an Type[] of interfaces using LINQ?
I'm trying to find all the methods that an interface grants me through reflection. I have a type array which I verify has only interfaces, from there I need to extract all the methods.Unfortunately, If I do something like typeof(IList).GetMethods() it only returns开发者_开发问答 the methods on IList not those on ICollection, or IEnumerable I've tried the following linq query but it doesn't return the methods found on the outer interfaces. How can I fix my query?
from outerInterfaces in interfaces
from i in outerInterfaces.GetInterfaces()
from m in i.GetMethods()
select m
If this was SQL I could do something like a recursive CTE with a union all, but I don't think such a syntax exist in C#. Can anyone help here?
How about something like this:
typeof(IList<>).GetMethods().Concat(typeof(IList<>)
.GetInterfaces()
.SelectMany(i => i.GetMethods()))
.Select(m => m.Name)
.ToList().ForEach(Console.WriteLine);
EDIT: Response to the comments.
Tested it with this code:
public interface IFirst
{
void First();
}
public interface ISecond : IFirst
{
void Second();
}
public interface IThird :ISecond
{
void Third();
}
public interface IFourth : IThird
{
void Fourth();
}
Test code:
typeof(IFourth).GetMethods().Concat(typeof(IFourth)
.GetInterfaces()
.SelectMany(i => i.GetMethods()))
.Select(m => m.Name)
.ToList().ForEach(Console.WriteLine);
And the output is:
Fourth
Third
Second
First
There's no "built-in" LINQ recursion (that I'm aware of), but you can create a boilerplate LINQ extension to get all descendants: (warning: compiled in notepad)
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;
}
}
}
}
Then you can use it like this, treating the base types a descendant nodes in a tree:
from ifaceType in interfaces.AllDescendants( t => t.GetInterfaces())
Given that you can compose your method selector:
from ifaceType in interfaces.AllDescendants( t=> t.GetInterfaces())
from m in ifaceType.GetMethods()
select m
which should give you all methods in all interfaces in the interfaces
collection, plus all base interfaces
精彩评论