2010-11-18 30 views
6

Tôi đang cố gắng tìm tất cả các phương thức mà giao diện cấp cho tôi thông qua phản ánh. Tôi có một mảng loại mà tôi xác minh chỉ có giao diện, từ đó tôi cần phải trích xuất tất cả các phương pháp. Thật không may, Nếu tôi làm một cái gì đó như typeof (IList) .GetMethods() nó chỉ trả về các phương pháp trên IList không phải trên ICollection, hoặc IEnumerable Tôi đã thử truy vấn LINQ sau đây nhưng nó không trả về các phương thức được tìm thấy trên các giao diện bên ngoài. Tôi làm cách nào để khắc phục truy vấn của mình?Nhận tất cả các phương thức trên một Type [] của các giao diện bằng LINQ?

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

Nếu đây là SQL tôi có thể làm một cái gì đó giống như CTE đệ quy với công đoàn, nhưng tôi không nghĩ cú pháp như vậy tồn tại trong C#. Bất cứ ai có thể giúp đỡ ở đây?

Trả lời

6

Làm thế nào về một cái gì đó như thế này:

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

EDIT: Đáp ứng cho ý kiến.

Tested nó với mã này: Mã

public interface IFirst 
    { 
     void First(); 
    } 

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

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

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

Test:

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

Và kết quả là:

Fourth 
Third 
Second 
First 
+0

@LukeH: Xem sửa của tôi. GetInterfaces() nhận tất cả các giao diện và đi lên cây phân cấp cho bạn. – BFree

+0

@ LukeH: Wow, tôi chưa bao giờ biết điều đó. Tôi rất muốn xem một số tài liệu xung quanh đó. Tôi cũng tự hỏi nếu các ngôn ngữ khác (đáng chú ý nhất là VB.Net) cũng vậy ... – BFree

+0

@BFree: Tôi vừa xóa nhận xét của mình trong khi tôi thực hiện một số nghiên cứu khác. Tôi ít hơn chắc chắn về nó, mặc dù tôi chắc chắn rằng tôi đọc nó ở đâu đó có thẩm quyền. Có nói rằng, tôi nghĩ rằng 'GetInterfaces' là đệ quy anyway mà sẽ làm cho hành vi thực tế không liên quan đến câu trả lời của bạn. – LukeH

4

Không có "built-in" LINQ đệ quy (mà tôi biết), nhưng bạn có thể tạo tiện ích soạn sẵn LINQ để có được tất cả các con cháu: (cảnh báo: biên soạn trong 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; 
      } 
     } 
    } 
} 

Sau đó, bạn có thể sử dụng nó như thế này, việc điều trị các loại cơ sở một nút hậu duệ trong một cây:

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

cho rằng bạn có thể soạn phương pháp chọn của bạn:

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

mà nên cung cấp cho bạn tất cả các phương pháp trong tất cả các giao diện trong bộ sưu tập interfaces, cộng với tất cả cơ sở giao diện

Các vấn đề liên quan