2012-09-06 18 views
18

Dado un objeto, ¿cómo puedo saber si ese objeto tiene propiedades virtuales?¿Cómo comprobar si una propiedad es virtual con reflejo?

var entity = repository.GetByID(entityId); 

He intentado buscar en:

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

pero no pudo discernir si alguna de las propiedades indicaría virtual.

Respuesta

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

O, para .NET 4 y abajo:

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

que conseguirá una lista de public virtual propiedades.

No funcionará para propiedades de solo escritura. Si es necesario, puede marcar CanRead y CanWrite manualmente y leer el método apropiado.

Por ejemplo:

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

También puedes, simplemente agarrar el primer descriptor de acceso:

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

ser manejado con seguridad las propiedades privadas que puede hacer: '(p.CanRead p.GetGetMethod (verdadero):? P.GetSetMethod (verdadero)). IsVirtual;' –

8

tratan con

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

Esto es un poco complicado, de sólo lectura debido a que una propiedad se puede, de sólo escritura o de lectura/escritura. Por lo tanto, es necesario comprobar ambos métodos subyacentes por ser virtual, de esta manera:

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

utilizar el método de GetAccessors, por ejemplo, para la primera propiedad:

acceso Get:

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

acceso set:

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

chequeando solo IsVirtual de descriptor de acceso de la propiedad le dará también la sección Interfaz propiedades que no están declarados virtual en su clase. Si por "propiedades virtuales" que quiere decir propiedades que se pueden anular en clase derivada también debe comprobar IsFinal (sellados):

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

Marque esta aplicación de ejemplo:

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

Ver this answer.

+0

Gracias por esto, muchas otras respuestas hablaron de 'isVirtual 'pero el control combinado' isFinal' lo hizo por mí. – webnoob

Cuestiones relacionadas