2012-11-26 21 views
7

Có cách nào chính thức hơn/không an toàn hơn để kiểm tra xem một số System.Reflection.MethodInfo có đề cập đến việc triển khai lớp học IDisposable.Dispose hơn các loại sau không?Kiểm tra xem phương pháp thực hiện IDisposable.Dispose với sự phản ánh

System.Reflection.MethodInfo methodInfo; 
methodInfo = ...; //methodInfo obtaining code here 
bool isDisposeMethod = methodInfo.Name == "Dispose"; 

Tôi đã biết lớp thực hiện IDisposable và do đó mà Dispose tồn tại, nhưng tôi đang sử dụng một khía cạnh PostSharp rằng nên thực hiện chức năng đặc biệt khi Dispose được gọi là (so với bất kỳ phương pháp lớp khác).

+1

Nếu một lớp thực hiện 'IDisposable', bạn được đảm bảo rằng nó triển khai' Vứt bỏ' - đó là điểm của giao diện. – Blorgbeard

+0

Tôi hiểu điều đó. Tôi biết rằng 'Dispose' tồn tại, nhưng tôi đang sử dụng một khía cạnh PostSharp nên thực hiện chức năng đặc biệt khi' Dispose' được gọi so với một hàm khác. Mặt sau PostSharp trả về chữ ký phương thức trong 'System.Reflection.MethodInfo'. –

Trả lời

6

Có:

class DisposableObject : IDisposable 
{ 
    public void Dispose() 
    { 
     //... 
    } 
} 

Bạn có thể làm:

Type t = typeof(DisposableObject); 

InterfaceMapping m = t.GetInterfaceMap(typeof(IDisposable)); 
MethodInfo mi = t.GetMethod("Dispose"); 

Console.WriteLine(mi == m.TargetMethods[0]); //true 

Vì vậy, tôi giả sử rằng bạn có MethodInfo đối với một số Dispose phương pháp trong lớp học của bạn (ở đây mi, chỉ cần thông qua GetMethod(string)). Sau đó, bạn sẽ cần phải có đối tượng InterfaceMapping Structure để triển khai IDisposable trong loại khai báo (tại đây DisposableObject) thông qua Type.GetInterfaceMap Method. Ở đó bạn có TargetMethods tham chiếu đến các phương thức thực sự triển khai thực hiện giao diện. Vì vậy, chúng tôi chỉ cần kiểm tra xem tham chiếu của bạn có bằng m.TargetMethods[0]IDisposable tuyên bố chỉ một phương pháp hay không.

Từ MSDN:

InterfaceMapping Cấu trúc

Lấy ánh xạ của một giao diện vào phương pháp thực tế trên một lớp mà thực hiện giao diện đó.

Sử dụng cấu trúc InterfaceMapping khi một loại thực hiện giao diện phương pháp sử dụng tên phương pháp khác so với những quy định của giao diện , hoặc khi một loại thực hiện nhiều giao diện trong đó có một phương pháp có cùng tên.

Để có cấu trúc InterfaceMapping, hãy sử dụng phương thức Type.GetInterfaceMap .


Một nhận xét: nếu lớp học của bạn có thể thực hiện IDisposable rõ ràng thì m.TargetMethods[0] sẽ tham khảo các implemetation rõ ràng. Vì vậy, tôi không chắc chắn có cách nào để có được nó là MethodInfo ngoại trừ InterfaceMapping (Xem Use Reflection to find Methods that implement explicit interfaces). Tình trạng này có thể dễ bị lỗi. Kiểm tra nó cho vấn đề cụ thể của bạn.

+0

Cảm ơn câu trả lời của bạn. Tôi không cố gắng kiểm tra xem đối tượng có triển khai 'IDisposable' hay không - đó chỉ là' bool test = myObj là IDispoable' - tôi đang thử kiểm tra xem một 'MethodInfo' cụ thể có liên quan đến việc thực hiện lớp' IDisposable.Dispose' hay không. . –

+0

@Fabian Tôi đã chỉnh sửa câu trả lời của mình, vui lòng xem lại câu trả lời – horgh

+0

Cảm ơn vì điều đó, có vẻ tuyệt vời! –

4

Tôi nghĩ đúng cách là GetInterface("IDisposable") trên loại và sau đó nhận thông tin phương pháp dựa trên đối tượng giao diện. Hơn bạn có thể so sánh phương pháp trong tay với phương thức trả về từ giao diện.

tên Chỉ cần kiểm tra là không đủ như

  • có thể có các phương pháp khác có cùng tên nhưng lập luận khác nhau
  • giao diện có thể được thực hiện explcitly.

Đây là lớp học cho thấy cả hai vấn đề:

class Test : IDisposable 
{ 
    public void Dispose(){} 
    public void Dispose(bool flag){} 
    void IDisposable.Dispose(){} 
} 
3

Tôi nghĩ rằng điều này có thể làm việc trong trường hợp của bạn, chứ không phải mã đẹp nhất của nó, nhưng nó sẽ trở lại nếu thông tin phương pháp của bạn đến từ một lớp IDisposible.

System.Reflection.MethodInfo methodInfo; 
methodInfo = ...; //methodInfo obtaining code here 
bool isDisposible = methodInfo.DeclaringType.FindInterfaces(new System.Reflection.TypeFilter((type, filter) => { return type.ToString() == filter.ToString(); }), "System.IDisposable").Any(); 

Không chắc chắn đây có phải là nội dung sau của bạn hay không.

+0

Đây là một câu trả lời tuyệt vời quá. Tôi đã cuộn lại với nhau những gì cả bạn và Konstantin Vasilcov đã đặt lại với nhau thành: 'bool isDisposible = methodInfo.DeclaringType.GetInterfaceMap (typeof (IDisposable)). TargetMethods.Where (x => x == methodInfo) .Any(); ' –

+2

Bạn có thể thả mệnh đề" Where "trong phương thức bạn có ở trên và chỉ sử dụng: ' bool isDisposible = methodInfo.DeclaringType.GetInterfaceMap (typeof (IDisposable)). TargetMethods.Any (x => x == methodInfo) ; ' –

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