Wie erhalte ich die Liste der Eigenschaften einer Klasse?


Antworten:


797

Betrachtung; für eine Instanz:

obj.GetType().GetProperties();

für einen Typ:

typeof(Foo).GetProperties();

zum Beispiel:

class Foo {
    public int A {get;set;}
    public string B {get;set;}
}
...
Foo foo = new Foo {A = 1, B = "abc"};
foreach(var prop in foo.GetType().GetProperties()) {
    Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(foo, null));
}

Nach Feedback ...

  • Übergeben Sie nullals erstes Argument an, um den Wert statischer Eigenschaften abzurufenGetValue
  • Verwenden Sie zum Anzeigen nicht öffentlicher Eigenschaften (zum Beispiel) GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)(das alle öffentlichen / privaten Instanzeigenschaften zurückgibt).

13
Der Vollständigkeit halber gibt es auch das ComponentModel, das von TypeDescriptor.GetProperties (...) verfügbar gemacht wird und dynamische Laufzeiteigenschaften ermöglicht (die Reflexion wird zur Kompilierungszeit festgelegt).
Marc Gravell

5
Vorschlag: Erweitern Sie die Antwort, um geschützte / private / statische / geerbte Eigenschaften abzudecken.
Richard

1
Die foreach-Anweisung, die Sie anzeigen, funktioniert sogar innerhalb der Klasse, deren Eigenschaften Sie erhalten möchten :)
halfpastfour.am

Es war mir nicht klar, wie die zusätzlichen Kommentare angegeben sind, aber wenn Sie alle 3 Flags verwenden, erhalten Sie auch internalEigenschaften. Vielleicht bin ich der einzige, der an der private/ non-public-Syntax hängen geblieben ist ?
Brichins

1
@Tadej Auf welches Framework zielen Sie ab? Wenn Sie .NET Core verwenden, müssen Sie sicherstellen, dass auf die using System.ReflectionDirektive und das System.Reflection.TypeExtensionsPaket verwiesen wird - dies stellt die fehlende API-Oberfläche über Erweiterungsmethoden
bereit

91

Sie können Reflection verwenden , um dies zu tun: (aus meiner Bibliothek - dies erhält die Namen und Werte)

public static Dictionary<string, object> DictionaryFromType(object atype)
{
    if (atype == null) return new Dictionary<string, object>();
    Type t = atype.GetType();
    PropertyInfo[] props = t.GetProperties();
    Dictionary<string, object> dict = new Dictionary<string, object>();
    foreach (PropertyInfo prp in props)
    {
        object value = prp.GetValue(atype, new object[]{});
        dict.Add(prp.Name, value);
    }
    return dict;
}

Dieses Ding funktioniert nicht für Eigenschaften mit einem Index - dafür (es wird unhandlich):

public static Dictionary<string, object> DictionaryFromType(object atype, 
     Dictionary<string, object[]> indexers)
{
    /* replace GetValue() call above with: */
    object value = prp.GetValue(atype, ((indexers.ContainsKey(prp.Name)?indexers[prp.Name]:new string[]{});
}

So erhalten Sie nur öffentliche Eigenschaften: ( siehe MSDN in der BindingFlags-Enumeration )

/* replace */
PropertyInfo[] props = t.GetProperties();
/* with */
PropertyInfo[] props = t.GetProperties(BindingFlags.Public)

Dies funktioniert auch bei anonymen Typen!
Um nur die Namen zu bekommen:

public static string[] PropertiesFromType(object atype)
{
    if (atype == null) return new string[] {};
    Type t = atype.GetType();
    PropertyInfo[] props = t.GetProperties();
    List<string> propNames = new List<string>();
    foreach (PropertyInfo prp in props)
    {
        propNames.Add(prp.Name);
    }
    return propNames.ToArray();
}

Und es ist ungefähr das gleiche für nur die Werte, oder Sie können verwenden:

GetDictionaryFromType().Keys
// or
GetDictionaryFromType().Values

Aber das ist etwas langsamer, würde ich mir vorstellen.


... aber atype.GetProperty (prp.Name) wird prp zurückgeben?
Marc Gravell

5
In Bezug auf das Bit "Öffentliche Eigenschaften" laut dem verknüpften MSDN-Artikel: "Hinweis Sie müssen Instanz oder Statisch zusammen mit Öffentlich oder Nicht öffentlich angeben, da sonst keine Mitglieder zurückgegeben werden." Der Beispielcode sollte also sein: t.GetProperties(BindingFlags.Instance | BindingFlags.Public)odert.GetProperties(BindingFlags.Static | BindingFlags.Public)
Carl Sharman

Ich habe nicht nach dem Code gesucht, sondern nach einer Erklärung für Reflexion und Wow, so sehr geschätzt! Machen Sie dies generisch und Sie könnten genauso gut sagen, dass Ihr Programm Superkräfte hat;)
Jaquarh

37
public List<string> GetPropertiesNameOfClass(object pObject)
{
    List<string> propertyList = new List<string>();
    if (pObject != null)
    {
        foreach (var prop in pObject.GetType().GetProperties())
        {
            propertyList.Add(prop.Name);
        }
    }
    return propertyList;
}

Diese Funktion dient zum Abrufen einer Liste der Klasseneigenschaften.


7
Möglicherweise möchten Sie dies ändern, um es zu verwenden yield return. Es ist keine große Sache, aber es ist eine bessere Art, es zu tun.
Matthew Haugen

1
Ich mag das, weil es (fast) die einzige Antwort ist, die das Wort Reflexion nicht enthält .

9
Dies nutzt jedoch immer noch die Reflexion.
GGG

2
Ich nehme an, das ist viel besser. pObject.GetType (). GetProperties (). Select (p => p.Name)
Enttäuscht am

23

Sie könnten den System.ReflectionNamespace mit dem Type.GetProperties()mehod verwenden:

PropertyInfo[] propertyInfos;
propertyInfos = typeof(MyClass).GetProperties(BindingFlags.Public|BindingFlags.Static);

23

Basierend auf der Antwort von @ MarcGravell ist hier eine Version, die in Unity C # funktioniert.

ObjectsClass foo = this;
foreach(var prop in foo.GetType().GetProperties()) {
    Debug.Log("{0}={1}, " + prop.Name + ", " + prop.GetValue(foo, null));
}

8

Das ist meine Lösung

public class MyObject
{
    public string value1 { get; set; }
    public string value2 { get; set; }

    public PropertyInfo[] GetProperties()
    {
        try
        {
            return this.GetType().GetProperties();
        }
        catch (Exception ex)
        {

            throw ex;
        }
    }

    public PropertyInfo GetByParameterName(string ParameterName)
    {
        try
        {
            return this.GetType().GetProperties().FirstOrDefault(x => x.Name == ParameterName);
        }
        catch (Exception ex)
        {

            throw ex;
        }
    }

    public static MyObject SetValue(MyObject obj, string parameterName,object parameterValue)
    {
        try
        {
            obj.GetType().GetProperties().FirstOrDefault(x => x.Name == parameterName).SetValue(obj, parameterValue);
            return obj;
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
}

6

Sie können Reflexion verwenden.

Type typeOfMyObject = myObject.GetType();
PropertyInfo[] properties =typeOfMyObject.GetProperties();

3

Ich stehe auch vor solchen Anforderungen.

Aus dieser Diskussion habe ich eine andere Idee,

Obj.GetType().GetProperties()[0].Name

Hier wird auch der Eigenschaftsname angezeigt.

Obj.GetType().GetProperties().Count();

Dies zeigt die Anzahl der Eigenschaften.

Dank an alle. Das ist eine nette Diskussion.


3

Hier ist @lucasjones Antwort verbessert. Ich habe Verbesserungen hinzugefügt, die im Kommentarbereich nach seiner Antwort erwähnt wurden. Ich hoffe, jemand wird dies nützlich finden.

public static string[] GetTypePropertyNames(object classObject,  BindingFlags bindingFlags)
{
    if (classObject == null)
    {
        throw new ArgumentNullException(nameof(classObject));
    }

        var type = classObject.GetType();
        var propertyInfos = type.GetProperties(bindingFlags);

        return propertyInfos.Select(propertyInfo => propertyInfo.Name).ToArray();
 }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.