2010-01-12 14 views
17

Hola, estoy trabajando en una biblioteca de clase usando C#, y tengo algunas clases con algunas propiedades.Excluir propiedad de getType(). GetProperties()

Solo quiero saber si puedo agregar algo para excluir algunas propiedades del getType(). GetProperties().

Un ejemplo de lo que quiero:

clase Test

{

public string one { get; set; } 

    public string two {get ; set;} 

}

y si hago esto:

void Main (string [] args) estáticas

{

Test t = new Test(); 

    Type ty = t.GetType(); 

    PropertyInfo[] pinfo = ty.GetProperties(); 

    foreach (PropertyInfo p in pinfo) 

    { 
     Console.WriteLine(p.Name); 

    } 

}

i desea que la salida sea algo como esto:

uno

o solo una de las propiedades.

¿Es posible hacer algo como eso? No sé si hay algún tipo de modificadores o anotaciones en C# que me permitan hacer lo que quiero.

Gracias.

+0

Sólo por curiosidad, ¿por qué ¿Le gustaría ocultar una propiedad pública de Reflection? –

+0

que sólo hay que construir una cierta representación de cadena de pares clave/valor de algunas clases para la muestra la representación de cadena que necesito es: uno = valueOfOne Y así para algunas propiedades, pero tengo algunas propiedades que i don No es necesario en la representación de cadena. – danielgomezdidier

Respuesta

20

Los métodos de extensión y atributos le ayudará a:

public class SkipPropertyAttribute : Attribute 
{ 
} 

public static class TypeExtensions 
{ 
    public static PropertyInfo[] GetFilteredProperties(this Type type) 
    { 
     return type.GetProperties().Where(pi => pi.GetCustomAttributes(typeof(SkipPropertyAttribute), true).Length == 0).ToArray(); 
    }  
} 

public class Test 
{ 
    public string One { get; set; } 

    [SkipProperty] 
    public string Two { get; set; } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var t = new Test(); 
     Type ty = t.GetType(); 

     PropertyInfo[] pinfo = ty.GetFilteredProperties(); 
     foreach (PropertyInfo p in pinfo) 
     { 
      Console.WriteLine(p.Name); 
     } 

     Console.ReadKey(); 
    } 
} 

ACTUALIZACIÓN:

poco más elegante aplicación de las GetFilteredProperties (gracias a Marc Gravell):

public static class TypeExtensions 
{ 
    public static PropertyInfo[] GetFilteredProperties(this Type type) 
    { 
     return type.GetProperties().Where(pi => !Attribute.IsDefined(pi, typeof(SkipPropertyAttribute))).ToArray(); 
    } 
} 
+2

Para obtener información, 'Attribute.IsDefined' puede ser más eficiente, pero una buena respuesta. –

+0

@Marc Gravell ¡gracias! – bniwredyc

+0

La solución más elegante funcionó perfectamente para mí. – MattD

0

Con el objeto PropertyInfo puede examinar GetCustomAttributes de la propiedad. De modo que podría agregar atributos a sus propiedades cuando los declare, y luego cuando refleje contra las propiedades, puede elegir solo las propiedades que están marcadas con los atributos que desea.

Por supuesto, si realmente quiere evitar de alguna manera que alguien obtenga de forma reflexiva sus propiedades, esta no es la solución que desea.

Editar: Lo siento, usted quiere GetCustomAttributes, corregido. Ver esto: http://msdn.microsoft.com/en-us/library/kff8s254.aspx

0

no creo que usted puede hacer esto directamente, pero se puede añadir sus propios atributos personalizados y filtrarlos por ti mismo ...

5

Se puede poner un atributo personalizado en su tipo.

public class DoNotIncludeAttribute : Attribute 
{ 
} 

public static class ExtensionsOfPropertyInfo 
{ 
    public static IEnumerable<T> GetAttributes<T>(this PropertyInfo propertyInfo) where T : Attribute 
    { 
     return propertyInfo.GetCustomAttributes(typeof(T), true).Cast<T>(); 
    } 
    public static bool IsMarkedWith<T>(this PropertyInfo propertyInfo) where T : Attribute 
    { 
     return property.GetAttributes<T>().Any(); 
    } 
} 
public class Test 
{ 
    public string One { get; set; } 

    [DoNotInclude] 
    public string Two { get; set; } 
} 

Luego, en su tiempo de ejecución, puede buscar las propiedades que no están ocultas.

foreach (var property in properties.Where(p => !p.IsMarkedWith<DoNotIncludeAttribute>()) 
{ 
    // do something... 
} 

No será realmente oculto, pero no aparecería en la enumeración.

+0

¡Esto es justo lo que necesito! Gracias – danielgomezdidier

+0

tiene un error tipográfico. en 'IsMarkedWith()' en lugar de 'property' debe escribirlo en' propertyInfo' –

1

No estoy seguro de qué es el dominio aquí, así que me estoy yendo por las ramas ...

Por lo general, lo que quiere hacer es usar Attribute s para etiquetar las propiedades para incluir en su búsqueda de metadatos, y no al revés.