2012-09-06 2 views

risposta

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

Oppure, per NET 4 e sotto:

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

che otterrà un elenco di virtuale pubblica proprietà.

Non funziona per le proprietà di sola scrittura. Se necessario, è possibile controllare manualmente CanRead e CanWrite e leggere il metodo appropriato.

Ad esempio:

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

Si potrebbe anche solo afferrare il primo di accesso:

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

Per gestire in modo sicuro le proprietà private che si possono fare: '(p.CanRead p.GetGetMethod (vero):? P.GetSetMethod (true)). IsVirtual;' –

8

provare con

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

Questo è un po 'difficile, di sola lettura perché una proprietà può essere, di sola scrittura o lettura/scrittura. Pertanto, è necessario controllare entrambi i metodi di base per essere virtuale, in questo modo:

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

utilizzare il metodo GetAccessors, ad esempio per la prima proprietà:

accesso get:

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

funzione di accesso Set:

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

Controllo solo IsVirtual di di accesso della struttura vi darà interfacciare anche proprietà che non sono dichiarati virtual nella classe. Se per "proprietà virtuale" intendi proprietà che è possibile sovrascrivere in classe derivata si dovrebbe anche verificare IsFinal (sigillato):

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

controllare questa applicazione di esempio:

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

Vedi this answer.

+0

Grazie per questo, un sacco di altre risposte parlato di 'isVirtual 'ma il controllo combinato' isFinal' lo ha fatto per me. – webnoob