2010-01-12 16 views
17

Ciao sto lavorando in una libreria di classi usando C# e ho alcune classi con alcune proprietà.Escludi proprietà da getType(). GetProperties()

Voglio solo sapere se posso aggiungere qualcosa per escludere alcune proprietà da getType(). GetProperties().

Un esempio di quello che voglio:

classe Test

{

public string one { get; set; } 

    public string two {get ; set;} 

}

e se faccio questo:

void Main (string [] args) statici

{

Test t = new Test(); 

    Type ty = t.GetType(); 

    PropertyInfo[] pinfo = ty.GetProperties(); 

    foreach (PropertyInfo p in pinfo) 

    { 
     Console.WriteLine(p.Name); 

    } 

}

Voglio che il dell'uscita essere qualcosa di simile:

uno

o solo una delle proprietà.

È possibile fare qualcosa del genere? non so se esiste qualche tipo di modificatori o annotazioni in C#, che mi permettono di fare ciò che voglio.

Grazie.

+0

Solo per curiosità, perché vuoi nascondere una proprietà pubblica da Reflection? –

+0

Ho solo bisogno di costruire qualche rappresentazione di stringa di coppie chiave/valore di alcune classi Per il campione la rappresentazione di stringa ho bisogno è: uno = valueOfOne E così per alcune proprietà, ma ho alcune proprietà che io don 'necessario nella rappresentazione stringa. – danielgomezdidier

risposta

20

metodi di estensione e gli attributi vi aiuteranno 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(); 
    } 
} 

UPDATE:

Poco più elegante attuazione dei GetFilteredProperties (grazie 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

Per informazioni, 'Attribute.IsDefined' può essere più efficiente, ma una buona risposta. –

+0

@Marc Gravell grazie! – bniwredyc

+0

La soluzione più elegante ha funzionato perfettamente per me. – MattD

0

Con l'oggetto PropertyInfo è possibile esaminare GetCustomAttributes della proprietà. Quindi puoi aggiungere attributi alle tue proprietà quando le dichiari, e poi quando rifletti sulle proprietà, puoi scegliere solo le proprietà che sono contrassegnate con gli attributi che desideri.

Ovviamente, se in realtà si desidera impedire a qualcuno di ottenere in modo riflessivo le proprietà, questa non è la soluzione che si desidera.

Modifica: Mi dispiace che tu voglia GetCustomAttributes, corretto. Vedere questo: http://msdn.microsoft.com/en-us/library/kff8s254.aspx

0

non credo che si può farlo direttamente, ma si potrebbe aggiungere i propri attributi personalizzati e filtrare i soli ...

5

Si potrebbe mettere un attributo personalizzato sul tuo 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; } 
} 

Quindi, nel runtime, è possibile cercare proprietà che non sono nascoste.

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

Non sarà realmente nascosto, ma non verrà visualizzato nell'elenco.

+0

Questo è proprio quello di cui ho bisogno !! Grazie – danielgomezdidier

+0

hai un errore di battitura. in 'IsMarkedWith()' invece di 'property' dovresti scriverlo in' propertyInfo' –

1

Non sono sicuro di cosa sia il dominio qui, quindi sto uscendo su un ramo ...

Di solito quello che si vuole fare è utilizzare Attribute s per contrassegnare le proprietà da includere nella vostra ricerca di metadati, non il contrario.