webentwicklung-frage-antwort-db.com.de

c # foreach (property in object) ... Gibt es eine einfache Möglichkeit, dies zu tun?

Ich habe eine Klasse mit mehreren Eigenschaften (alle sind Strings, wenn es einen Unterschied macht).
Ich habe auch eine Liste, die viele verschiedene Instanzen der Klasse enthält.

Beim Erstellen einiger Komponententests für meine Klassen entschied ich, dass ich jedes Objekt in der Liste durchlaufen und dann jede Eigenschaft des Objekts durchlaufen sollte.

Ich dachte, das wäre so einfach wie ...

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

Aber das hat nicht funktioniert! : ( Ich bekomme diesen Fehler ...

"Die foreach-Anweisung kann nicht mit Variablen des Typs 'Application.Object' arbeiten, da 'Application.Object' keine öffentliche Definition für 'GetEnumerator' enthält."

Kennt jemand einen Weg, dies ohne Tonnen von Wenns und Loops zu tun oder ohne etwas zu komplexes zu bekommen?

69
Jammerz858

Probieren Sie es aus:

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

Beachten Sie auch, dass Type.GetProperties() eine Überladung enthält, die eine Reihe von Bindungsflags akzeptiert, sodass Sie Eigenschaften nach anderen Kriterien wie der Zugriffsebene herausfiltern können. Weitere Informationen finden Sie unter MSDN: Type.GetProperties-Methode (BindingFlags) Last but not least Vergessen Sie nicht, die Assemblyreferenz "system.Reflection" hinzuzufügen.

Um beispielsweise alle öffentlichen Eigenschaften aufzulösen:

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

Bitte lassen Sie mich wissen, ob dies wie erwartet funktioniert.

112
sll

Sie können alle nicht indizierten Eigenschaften eines Objekts wie folgt durchlaufen:

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

Da GetProperties() indexers sowie einfache Eigenschaften zurückgibt, benötigen Sie einen zusätzlichen Filter, bevor Sie GetValue aufrufen, um zu wissen, dass null sicher als zweiter Parameter übergeben werden kann.

Möglicherweise müssen Sie den Filter weiter ändern, um schreibgeschützte und sonst nicht zugängliche Eigenschaften auszusondern.

23
dasblinkenlight

Sie sind fast da, Sie müssen nur die Eigenschaften aus dem Typ abrufen, anstatt zu erwarten, dass die Eigenschaften in Form einer Sammlung oder eines Eigenschaftsbeutels verfügbar sind:

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

Von dort kannst du gerne so :

property.Name
property.GetValue(obj, null)

Mit GetValue können Sie mit dem zweiten Parameter Indexwerte angeben, die mit Eigenschaften funktionieren, die Sammlungen zurückgeben. Da eine Zeichenfolge eine Sammlung von Zeichen ist, können Sie auch einen Index angeben, um bei Bedarf ein Zeichen zurückzugeben.

17
Grant Thomas

Sicher kein Problem:

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

Verwenden Sie Reflection, um dies zu tun

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

Ein kleines Wort der Vorsicht: Wenn "etwas tun" bedeutet, den Wert der tatsächlichen Eigenschaft zu aktualisieren, die Sie besuchen, UND wenn eine Strukturtypeigenschaft entlang des Pfads vom Stammobjekt zur besuchten Eigenschaft vorhanden ist, wird die von Ihnen vorgenommene Änderung an der Eigenschaft übernommen wird nicht im Stammobjekt reflektiert.

0
Dogu Arslan

Ich konnte keine der oben genannten Möglichkeiten zur Arbeit bekommen, aber das hat funktioniert. Der Benutzername und das Kennwort für DirectoryEntry sind optional.

   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