webentwicklung-frage-antwort-db.com.de

Wie können Sie die Eigenschaften einer Klasse durchlaufen?

Gibt es eine Möglichkeit in c #, die Eigenschaften einer Klasse zu durchlaufen?

Grundsätzlich habe ich eine Klasse, die eine große Anzahl von Eigenschaften enthält (sie enthält im Wesentlichen die Ergebnisse einer großen Datenbankabfrage) . Ich muss diese Ergebnisse als CSV-Datei ausgeben, daher muss jeder Wert an einen String angehängt werden.

Die offensichtliche Art, jeden Wert manuell an eine Zeichenfolge anzuhängen, aber gibt es eine Möglichkeit, das Ergebnisobjekt effektiv zu durchlaufen und den Wert für jede Eigenschaft nacheinander hinzuzufügen?

46
Sergio

Sicher; Sie können das auf viele Arten tun. Beginnend mit Reflektion (Beachten Sie, das ist langsam - OK für moderate Datenmengen):

var props = objectType.GetProperties();
foreach(object obj in data) {
    foreach(var prop in props) {
        object value = prop.GetValue(obj, null); // against prop.Name
    }
}

Jedoch; Für größere Datenmengen lohnt es sich, diese effizienter zu gestalten. Zum Beispiel verwende ich hier die Expression-API, um einen Delegaten vorkompilieren zu können, der wie jede Eigenschaft schreibt. Der Vorteil hier ist, dass keine Reflexion pro Zeile erfolgt (dies sollte für große Datenmengen wesentlich schneller sein):

static void Main()
{        
    var data = new[] {
       new { Foo = 123, Bar = "abc" },
       new { Foo = 456, Bar = "def" },
       new { Foo = 789, Bar = "ghi" },
    };
    string s = Write(data);        
}
static Expression StringBuilderAppend(Expression instance, Expression arg)
{
    var method = typeof(StringBuilder).GetMethod("Append", new Type[] { arg.Type });
    return Expression.Call(instance, method, arg);
}
static string Write<T>(IEnumerable<T> data)
{
    var props = typeof(T).GetProperties();
    var sb = Expression.Parameter(typeof(StringBuilder));
    var obj = Expression.Parameter(typeof(T));
    Expression body = sb;
    foreach(var prop in props) {            
        body = StringBuilderAppend(body, Expression.Property(obj, prop));
        body = StringBuilderAppend(body, Expression.Constant("="));
        body = StringBuilderAppend(body, Expression.Constant(prop.Name));
        body = StringBuilderAppend(body, Expression.Constant("; "));
    }
    body = Expression.Call(body, "AppendLine", Type.EmptyTypes);
    var lambda = Expression.Lambda<Func<StringBuilder, T, StringBuilder>>(body, sb, obj);
    var func = lambda.Compile();

    var result = new StringBuilder();
    foreach (T row in data)
    {
        func(result, row);
    }
    return result.ToString();
}
48
Marc Gravell
foreach (PropertyInfo prop in typeof(MyType).GetProperties())
{
    Console.WriteLine(prop.Name);
}
18
Steven

Ich habe auf dieser Seite verschiedene Empfehlungen ausprobiert, ich konnte keine davon wirklich zur Arbeit bringen. Ich habe mit der obersten Antwort angefangen (Sie werden feststellen, dass meine Variablen ähnlich benannt werden) und habe sie nur selbst durchgearbeitet. Das ist es, was ich zu arbeiten bekam - hoffentlich kann es jemand anderem helfen.

var prop = emp.GetType().GetProperties();     //emp is my class
    foreach (var props in prop)
      {
        var variable = props.GetMethod;

        empHolder.Add(variable.Invoke(emp, null).ToString());  //empHolder = ArrayList
      }

*** Ich sollte erwähnen, dass dies nur funktionieren wird, wenn Sie get; set; (öffentliche) Eigenschaften.

5
Aaron

Sie können eine Liste der Eigenschaften von Oject erstellen

  IList<PropertyInfo> properties = typeof(T).GetProperties().ToList();

Und dann mit einem foreach in die Liste navigieren ..

   foreach (var property in properties)
            {
              here's code...
            }
3
bAN
var csv = string.Join(",",myObj
    .GetType()
    .GetProperties(BindingFlags.Public | BindingFlags.Instance)
    .Select(p => p.GetValue(myObj, null).ToString())
    .ToArray());
1
Dean Chalk

Verwenden Sie so etwas wie

StringBuilder csv = String.Empty;
PropertyInfo[] ps this.GetType().GetProperties();
foreach (PropertyInfo p in ps)
{
    csv.Append(p.GetValue(this, null);
    csv.Append(",");
}
1
Ive
string notes = "";

Type typModelCls = trans.GetType(); //trans is the object name
foreach (PropertyInfo prop in typModelCls.GetProperties())
{
    notes = notes + prop.Name + " : " + prop.GetValue(trans, null) + ",";
}
notes = notes.Substring(0, notes.Length - 1);

Wir können dann den Anmerkungsstring als Spalte in die Protokolltabelle oder in eine Datei schreiben. Sie müssen System.Reflection verwenden, um PropertyInfo verwenden zu können 

0

eigenschaftenwerte von einfachen Klassenobjekten abrufen ....

class Person
{
    public string Name { get; set; }
    public string Surname { get; set; }
    public int Age { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var person1 = new Person
        {
            Name = "John",
            Surname = "Doe",
            Age = 47
        };

        var props = typeof(Person).GetProperties();
        int counter = 0;

        while (counter != props.Count())
        {
            Console.WriteLine(props.ElementAt(counter).GetValue(person1, null));
            counter++;
        }
    }
}
0
donibaloni

so können Sie die Eigenschaften in vb.net durchlaufen, das gleiche Konzept in c #. Übersetzen Sie einfach die Syntax:

 Dim properties() As PropertyInfo = Me.GetType.GetProperties(BindingFlags.Public Or BindingFlags.Instance)
            If properties IsNot Nothing AndAlso properties.Length > 0 Then
                properties = properties.Except(baseProperties)
                For Each p As PropertyInfo In properties
                    If p.Name <> "" Then
                        p.SetValue(Me, Date.Now, Nothing)  'user p.GetValue in your case
                    End If
                Next
            End If
0
Ali Tarhini

Durchlaufen von Eigenschaften

Type t = typeof(MyClass);
foreach (var property in t.GetProperties())
{                
}
string target = "RECEIPT_FOOTER_MESSAGE_LINE" + index + "Column";
PropertyInfo prop = xEdipV2Dataset.ReceiptDataInfo.GetType().GetProperty(target);
Type t = xEdipV2Dataset.ReceiptDataInfo.RECEIPT_FOOTER_MESSAGE_LINE10Column.GetType();
prop.SetValue(t, fline, null);

Achtung: Zielobjekt muss einstellbar sein

0
dewelloper