2008-12-05 9 views
1

Je réalise une validation de base simple sur différents types. Le test en cours sur lequel je travaille consiste à vérifier que leurs propriétés sont bien remplies. Dans ce cas, peuplé est défini comme non nul, ayant une longueur supérieure à zéro (si une chaîne), ou non égale à 0 (si un entier). La partie "délicate" de ce test est que certaines propriétés sont immunisées contre cette vérification. À l'heure actuelle, j'utilise une instruction géante if qui supprime les propriétés qui n'ont pas besoin d'être vérifiées.Filtrer les propriétés d'un objet par son nom

//Gets all the properties of the currect feature. 
System.Reflection.PropertyInfo[] pi = t.GetProperties(); 

for(int i = 0; i < pi.Length; i++) 
{ 
    if(!pi[i].Name.Equals("PropertyOne") 
    && !pi[i].Name.Equals("PropertyTwo") 
    && !pi[i].Name.Equals("PropertyThree") 
      //... repeat a bunch more times 
    && !pi[i].Name.IndexOf("ValueOne") != -1 
    && !pi[i].Name.IndexOf("ValueTwo") != -1 
      //... repeat a bunch more times 
    { 
     //Perform the validation check. 
    }     
} 

lors du profilage, je remarquai l'instruction if est en fait moins performante que la réflexion (pas que la réflexion est ultra-rapide). Existe-t-il un moyen plus efficace de filtrer les propriétés de plusieurs types différents?

J'ai pensé à une expression régulière massive mais je ne suis pas sûr de la façon de la formater, en plus elle serait probablement illisible compte tenu de sa taille. J'ai également envisagé de stocker les valeurs dans une liste puis d'utiliser Linq mais je ne suis pas sûr de savoir comment gérer les cas qui utilisent String.IndexOf() pour trouver si la propriété contient une certaine valeur.

Merci d'avance.

Répondre

2

Faire un HashSet "exactNames" avec PropertyOne, PropertyTwo etc, puis une liste "partialNames" avec PremièreValeur, ValueTwo etc. Puis:

var matchingProperties = pi.Where(exactNames.Contains(pi.Name) || 
          partialNames.Any(name => pi.Name.Contains(name)); 

foreach (PropertyInfo property in matchingProperties) 
{ 
    // Stuff 
} 

(. Odd indenter juste pour éviter l'emballage)

Notez que vous pouvez mettre en cache l'ensemble des propriétés à valider pour chaque type, vous n'avez donc besoin de passer cette vérification qu'une seule fois par type.

0

Votre idée aide à accélérer mon programme, merci. Cependant, vous avez rencontré des problèmes de syntaxe, en plus vous correspondiez aux éléments trouvés dans les listes et j'avais besoin d'éléments qui ne figuraient pas dans la liste. Voici le code que j'ai fini par utiliser.

List<System.Reflection.PropertyInfo> pi = type.GetProperties().ToList(); 

var matchingProperties = pi.Where(prop => !PropertyExclusionSet.Contains(prop.Name) 
&& !PropertiesPartialSet.Any(name => prop.Name.Contains(name))); 
0

Vous pourriez envisager de décorer vos propriétés avec des attributs qui indiquent quelle action doit être effectuée.

public class MyClass { 

    [CheckMe] 
    public int PropertyOne { get; set; } 

    [DontCheckMe] 
    public int PropertyTwo { get; set; } 

} 
Questions connexes