Wie erhalte ich die Liste der Eigenschaften einer Klasse?

597

Wie erhalte ich eine Liste aller Eigenschaften einer Klasse?

nawfal
quelle

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).
Marc Gravell
quelle
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.

Lucas Jones
quelle
... 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.

DDTBNT
quelle
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);
Jon Limjap
quelle
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));
}
Jacksonkr
quelle
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;
        }
    }
}
Ali Osman Mollahüseyinoğlu
quelle
6

Sie können Reflexion verwenden.

Type typeOfMyObject = myObject.GetType();
PropertyInfo[] properties =typeOfMyObject.GetProperties();
Daan
quelle
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.

Singaravelan
quelle
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();
 }
Imants Volkovs
quelle