2012-09-06 55 views
18

Cho một đối tượng, làm thế nào tôi có thể biết được đối tượng đó có các thuộc tính ảo không?Cách kiểm tra xem thuộc tính có ảo không?

var entity = repository.GetByID(entityId); 

Tôi cố gắng nhìn vào:

PropertyInfo[] properties = entity.GetType().GetProperties(); 

Nhưng không thể phân biệt nếu bất kỳ thuộc tính sẽ chỉ ảo.

Trả lời

32
PropertyInfo[] properties = entity.GetType().GetProperties() 
    .Where(p => p.GetMethod.IsVirtual).ToArray(); 

Hoặc, cho .NET 4 và dưới đây:

PropertyInfo[] properties = entity.GetType().GetProperties() 
    .Where(p => p.GetGetMethod().IsVirtual).ToArray(); 

Đó sẽ nhận được một danh sách các công ảo tính chất.

Nó sẽ không hoạt động đối với thuộc tính chỉ ghi. Nếu cần, bạn có thể kiểm tra CanReadCanWrite theo cách thủ công và đọc phương thức thích hợp.

Ví dụ:

PropertyInfo[] properties = entity.GetType().GetProperties() 
    .Where(p => (p.CanRead ? p.GetMethod : p.SetMethod).IsVirtual).ToArray(); 

Bạn cũng có thể chỉ cần lấy các accessor đầu tiên:

PropertyInfo[] properties = entity.GetType().GetProperties() 
    .Where(p => p.GetAccessors()[0].IsVirtual).ToArray(); 
+0

Để xử lý một cách an toàn các thuộc tính riêng tư bạn có thể thực hiện: '(p.CanRead? P.GetGetMethod (true): p.GetSetMethod (true)). IsVirtual;' –

8

thử với

typeof(YourClass).GetProperty("YouProperty").GetGetMethod().IsVirtual; 
3

Đây là một chút khó khăn, bởi vì một tài sản có thể được chỉ đọc, viết-chỉ, hoặc đọc/ghi. Vì vậy, bạn cần phải kiểm tra cả hai phương pháp cơ bản cho việc ảo, như thế này:

PropertyInfo pi = ... 
var isVirtual = (pi.CanRead && pi.GetMethod.IsVirtual) 
      || (pi.CanWrite && pi.SetMethod.IsVirtual); 
5

Sử dụng phương pháp GetAccessors, ví dụ cho các tài sản đầu tiên:

Nhận accessor:

properties[0].GetAccessors()[0].IsVirtual 

Set accessor:

properties[0].GetAccessors()[1].IsVirtual 
11

Kiểm tra chỉ IsVirtual của accessor bất động sản sẽ cung cấp cho bạn cũng giao diện tính năng mà không khai báo virtual trong lớp học của bạn. Nếu bởi "tài sản ảo" bạn có nghĩa là tính năng mà bạn có thể ghi đè trong lớp có nguồn gốc bạn cũng nên kiểm tra IsFinal (đóng dấu):

var accessor = typeof(MyType).GetProperty("MyProp").GetAccessors()[0]; 
var isVirtual = accessor.IsVirtual && ! accessor.IsFinal; 

Kiểm tra ứng dụng mẫu này:

using System; 

namespace VirtualPropertyReflection 
{ 
    interface I 
    { 
     int P1 { get; set; } 
     int P2 { get; set; } 
    } 

    class A : I 
    { 
     public int P1 { get; set; } 
     public virtual int P2 { get; set; } 

     static void Main() 
     { 
      var p1accessor = typeof(A).GetProperty("P1").GetAccessors()[0]; 
      Console.WriteLine(p1accessor.IsVirtual); // True 
      Console.WriteLine(p1accessor.IsFinal); // True 

      var p2accessor = typeof(A).GetProperty("P2").GetAccessors()[0]; 
      Console.WriteLine(p2accessor.IsVirtual); // True 
      Console.WriteLine(p2accessor.IsFinal); // False 
     } 
    } 
} 

Xem this answer.

+0

Cảm ơn điều này, rất nhiều câu trả lời khác đã nói về 'isVirtual 'nhưng kiểm tra' isFinal' kết hợp đã làm điều đó cho tôi. – webnoob

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