2010-11-18 6 views
6

Sto cercando di trovare tutti i metodi che un'interfaccia mi garantisce attraverso la riflessione. Ho un array di tipo che verifica abbia solo interfacce, da lì ho bisogno di estrarre tutti i metodi. Sfortunatamente, se faccio qualcosa come typeof (IList) .GetMethods() restituisce solo i metodi su IList non quelli su ICollection, o IEnumerable Ho provato la seguente query linq ma non restituisce i metodi trovati sulle interfacce esterne. Come posso risolvere la mia domanda?Ottieni tutti i metodi su un Tipo [] di interfacce usando LINQ?

from outerInterfaces in interfaces 
from i in outerInterfaces.GetInterfaces() 
from m in i.GetMethods() 
select m 

Se questo è stato SQL avrei potuto fare qualcosa di simile a una CTE ricorsiva con tutto un sindacato, ma non credo che una tale sintassi esiste in C#. Qualcuno può aiutarti qui?

risposta

6

Che ne dite di qualcosa di simile:

typeof(IList<>).GetMethods().Concat(typeof(IList<>) 
       .GetInterfaces() 
       .SelectMany(i => i.GetMethods())) 
       .Select(m => m.Name) 
       .ToList().ForEach(Console.WriteLine); 

EDIT: Risposta ai commenti.

provato con questo codice: il codice

public interface IFirst 
    { 
     void First(); 
    } 

    public interface ISecond : IFirst 
    { 
     void Second(); 
    } 

    public interface IThird :ISecond 
    { 
     void Third(); 
    } 

    public interface IFourth : IThird 
    { 
     void Fourth(); 
    } 

prova:

 typeof(IFourth).GetMethods().Concat(typeof(IFourth) 
      .GetInterfaces() 
      .SelectMany(i => i.GetMethods())) 
      .Select(m => m.Name) 
      .ToList().ForEach(Console.WriteLine); 

e l'uscita è:

Fourth 
Third 
Second 
First 
+0

@LukeH: Vedere la mia modifica. GetInterfaces() ottiene tutte le interfacce e cammina per l'albero della gerarchia. – BFree

+0

@LukeH: Wow, non l'ho mai saputo. Mi piacerebbe vedere qualche documentazione in merito. Mi chiedo anche se altre lingue (in particolare VB.Net) lo facciano anche ... – BFree

+0

@BFree: Ho appena cancellato il mio commento mentre faccio qualche altra ricerca. Ne sono meno sicuro, anche se sono sicuro di averlo letto da qualche parte autorevole. Detto questo, penso che "GetInterfaces" sia ricorsivo in ogni caso, il che renderebbe il comportamento reale irrilevante alla tua risposta. – LukeH

4

Non c'è LINQ ricorsione "built-in" (che io sappia), ma è possibile creare un'estensione boilerplate LINQ per ottenere tutti i discendenti: (attenzione: compilato 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; 
      } 
     } 
    } 
} 

Poi è possibile utilizzarlo in questo modo, trattando i tipi di base a nodi discendenti in un albero:

from ifaceType in interfaces.AllDescendants(t => t.GetInterfaces()) 

Dato che si può comporre il selettore del metodo:

from ifaceType in interfaces.AllDescendants(t=> t.GetInterfaces()) 
from m in ifaceType.GetMethods() 
select m 

che dovrebbe darvi tutti i metodi di tutte le interfacce della collezione interfaces, oltre a tutte le interfacce di base

Problemi correlati