web-dev-qa-db-fra.com

c # foreach (propriété dans l'objet) ... Existe-t-il un moyen simple de procéder?

J'ai une classe contenant plusieurs propriétés (toutes sont des chaînes si cela fait une différence).
J'ai aussi une liste, qui contient beaucoup d'instances différentes de la classe.

Lors de la création de tests unitaires pour mes classes, j'ai décidé de faire une boucle sur chaque objet de la liste, puis sur chaque propriété de cet objet ...

Je pensais que cela serait aussi simple que ...

foreach (Object obj in theList)
{
     foreach (Property theProperties in obj)
     {
         do some stufff!!;
     }
}

Mais cela n'a pas fonctionné! : ( Je reçois cette erreur ...

"L'instruction foreach ne peut pas fonctionner sur les variables de type 'Application.Object' car 'Application.Object' ne contient pas de définition publique pour 'GetEnumerator'"

Est-ce que quelqu'un connaît un moyen de faire cela sans des tonnes de si et de boucles ou sans entrer dans quelque chose de trop complexe?

69
Jammerz858

Essayez ceci:

foreach (PropertyInfo propertyInfo in obj.GetType().GetProperties())
{
   // do stuff here
}

Veuillez également noter que Type.GetProperties() a une surcharge qui accepte un ensemble d’indicateurs de liaison afin que vous puissiez filtrer les propriétés sur des critères différents tels que le niveau d’accessibilité. Pour plus de détails, voir MSDN: Type.GetProperties, méthode (BindingFlags) Last but not least n'oubliez pas d'ajouter la référence d'assemblage "system.Reflection".

Par exemple pour résoudre toutes les propriétés publiques:

foreach (var propertyInfo in obj.GetType()
                                .GetProperties(
                                        BindingFlags.Public 
                                        | BindingFlags.Instance))
{
   // do stuff here
}

S'il vous plaît laissez-moi savoir si cela fonctionne comme prévu.

112
sll

Vous pouvez parcourir toutes les propriétés non indexées d'un objet comme ceci:

var s = new MyObject();
foreach (var p in s.GetType().GetProperties().Where(p => !p.GetGetMethod().GetParameters().Any())) {
    Console.WriteLine(p.GetValue(s, null));
}

Étant donné que GetProperties() renvoie indexers ainsi que des propriétés simples, vous devez disposer d'un filtre supplémentaire avant d'appeler GetValue pour savoir qu'il est prudent de passer null en tant que second paramètre.

Vous devrez peut-être modifier davantage le filtre afin d'éliminer les propriétés en écriture seule et les propriétés inaccessibles.

23
dasblinkenlight

Vous y êtes presque, il vous suffit d’obtenir les propriétés du type, au lieu d’attendre que les propriétés soient accessibles sous la forme d’une collection ou d’un sac de propriétés:

var property in obj.GetType().GetProperties()

À partir de là vous pouvez accéder comme suit :

property.Name
property.GetValue(obj, null)

Avec GetValue, le second paramètre vous permettra de spécifier des valeurs d’index, ce qui fonctionnera avec les propriétés renvoyant des collections - puisqu’une chaîne est une collection de caractères, vous pouvez également spécifier un index pour renvoyer un caractère si besoin est.

17
Grant Thomas

Bien sûr pas de problème:

foreach(object item in sequence)
{
    if (item == null) continue;
    foreach(PropertyInfo property in item.GetType().GetProperties())
    {
        // do something with the property
    }
}
17
Eric Lippert

Utilisez la réflexion pour le faire

SomeClass A = SomeClass(...)
PropertyInfo[] properties = A.GetType().GetProperties();
3
Arion

Un petit mot d'avertissement, si "faire des choses" signifie mettre à jour la valeur de la propriété réelle que vous visitez ET s'il existe une propriété de type struct le long du chemin d'accès de l'objet racine à la propriété visitée, les modifications apportées à la propriété ne pas être reflété sur l'objet racine.

0
Dogu Arslan

Je ne pouvais obtenir aucune des méthodes décrites ci-dessus, mais cela fonctionnait. Le nom d'utilisateur et le mot de passe pour DirectoryEntry sont facultatifs.

   private List<string> getAnyDirectoryEntryPropertyValue(string userPrincipalName, string propertyToSearchFor)
    {
        List<string> returnValue = new List<string>();
        try
        {
            int index = userPrincipalName.IndexOf("@");
            string originatingServer = userPrincipalName.Remove(0, index + 1);
            string path = "LDAP://" + originatingServer; //+ @"/" + distinguishedName;
            DirectoryEntry objRootDSE = new DirectoryEntry(path, PSUsername, PSPassword);
            var objSearcher = new System.DirectoryServices.DirectorySearcher(objRootDSE);
            objSearcher.Filter = string.Format("(&(UserPrincipalName={0}))", userPrincipalName);
            SearchResultCollection properties = objSearcher.FindAll();

            ResultPropertyValueCollection resPropertyCollection = properties[0].Properties[propertyToSearchFor];
            foreach (string resProperty in resPropertyCollection)
            {
                returnValue.Add(resProperty);
            }
        }
        catch (Exception ex)
        {
            returnValue.Add(ex.Message);
            throw;
        }

        return returnValue;
    }
0
Bbb