开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜