2012-09-06 10 views
18

Jak określić, czy obiekt ma właściwości wirtualne, biorąc pod uwagę obiekt?Jak sprawdzić, czy nieruchomość jest wirtualna z odbiciem?

var entity = repository.GetByID(entityId); 

Próbowałem patrząc w:

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

Ale nie mógł rozpoznać, czy którąkolwiek z właściwości wskazywałoby wirtualny.

Odpowiedz

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

lub dla .NET 4 i poniżej:

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

Że dostanie listę wirtualny publicznego nieruchomości.

Nie będzie działać dla właściwości tylko do zapisu. Jeśli zajdzie taka potrzeba, możesz ręcznie sprawdzić CanRead i CanWrite i przeczytać odpowiednią metodę.

Na przykład:

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

Można też po prostu chwyć pierwszy akcesor:

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

Aby bezpiecznie obsługiwać właściwości prywatnych można zrobić: '(p.CanRead p.GetGetMethod (true): p.GetSetMethod (true)). IsVirtual;' –

8

spróbuj

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

To jest trochę skomplikowane, ponieważ nieruchomość może być tylko do odczytu, tylko do zapisu lub odczytu/zapisu. Dlatego trzeba sprawdzić obie metody leżące za bycie wirtualnym, tak:

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

użyć metody GetAccessors, na przykład na pierwszym miejscu:

Get accessor:

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

Zestaw accessor:

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

Sprawdzanie tylko IsVirtual z akcesor miejscu zakwaterowania da Ci również interfejs właściwości, które nie są zadeklarowane virtual w klasie. Jeśli przez „właściwości wirtualnych” znaczy właściwości, które można przesłonić w klasie pochodnej należy również sprawdzić IsFinal (zamknięte):

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

Zaznacz tę przykładową aplikację:

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 
     } 
    } 
} 

Zobacz this answer.

+0

Dzięki za to, wiele innych odpowiedzi mówił o 'isVirtual 'ale połączona kontrola' isFinal' zrobiła to za mnie. – webnoob

Powiązane problemy