2010-11-18 8 views
6

私は、インターフェイスがリフレクションを通して私に許可するすべてのメソッドを見つけようとしています。私は型の配列を持っているだけですが、そこからはすべてのメソッドを抽出する必要があることを確認します。不幸にも、私がtypeof(IList).GetMethods()のようにICollection上のメソッドではなくIListのメソッドを返しますIEnumerable 次のようなlinqクエリを試しましたが、外側のインターフェイスにあるメソッドは返されません。クエリを修正するにはどうすればよいですか?これはSQLだった場合LINQを使用して、インタフェースのタイプ[]のすべてのメソッドを取得しますか?

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

は、私はすべての労働組合で再帰CTEのような何かを行うことができますが、私は、このような構文は、C#には存在しないと思います。誰でもここで助けることができますか?

答えて

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 
+0

@LukeH:私の編集を参照してください。 GetInterfaces()はすべてのインターフェイスを取得し、階層ツリーを上に向かって歩きます。 – BFree

+0

@ルーク:うわー、私はそれを知らなかった。私はその周りのいくつかのドキュメントを見たいと思う。私はまた、他の言語(特にVB.Net)でも同様のことがあるのだろうかと思っています。 – BFree

+0

@BFree:私はいくつかの研究をしている間に私のコメントを削除しました。私は確信していますが、確かに私はそれをどこかに読んでいます。だから、私は 'GetInterfaces'はとにかくあなたの答えに無関係な実際の動作をさせる再帰的だと思います。 – LukeH

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コレクション内のすべてのインターフェイスのすべてのメソッドを与えるべき

、プラスのすべてのベースのインターフェイス

関連する問題