Как вы можете зациклить свойства класса? - PullRequest
47 голосов
/ 25 ноября 2010

Есть ли в c # способ перебрать свойства класса?

По сути, у меня есть класс, который содержит большое количество свойств (в основном он содержит результаты большого запроса к базе данных). Мне нужно вывести эти результаты в виде файла CSV, поэтому необходимо добавить каждое значение в строку.

Очевидный способ вручную добавить каждое значение в строку, но есть ли способ эффективно зациклить объект результатов и по очереди добавить значение для каждого свойства?

Ответы [ 11 ]

48 голосов
/ 25 ноября 2010

Конечно;Вы можете сделать это разными способами;начиная с размышления (обратите внимание, это медленно - ОК для средних объемов данных):

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

Однако;для больших объемов данных стоило бы сделать это более эффективным;например, здесь я использую API Expression для предварительной компиляции делегата, который просматривает записи каждого свойства - здесь преимущество заключается в том, что отражение для каждой строки не выполняется (это должно быть значительно быстрее для больших объемов данных):

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();
}
18 голосов
/ 25 ноября 2010
foreach (PropertyInfo prop in typeof(MyType).GetProperties())
{
    Console.WriteLine(prop.Name);
}
5 голосов
/ 14 марта 2013

Я попробовал различные рекомендации на этой странице, я не мог заставить их работать.Я начал с верхнего ответа (вы заметите, что мои переменные имеют одинаковое имя), и просто проработал его самостоятельно.Это то, что я получил на работу - надеюсь, это может помочь кому-то еще.

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
      }

*** Я должен упомянуть, что это будет работать, только если вы используете get; set;(публичные) свойства.

3 голосов
/ 25 ноября 2010

Вы можете составить список свойств объекта

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

, а затем использовать foreach для навигации по списку.

   foreach (var property in properties)
            {
              here's code...
            }
1 голос
/ 25 ноября 2010
var csv = string.Join(",",myObj
    .GetType()
    .GetProperties(BindingFlags.Public | BindingFlags.Instance)
    .Select(p => p.GetValue(myObj, null).ToString())
    .ToArray());
1 голос
/ 25 ноября 2010

Используйте что-то вроде

StringBuilder csv = String.Empty;
PropertyInfo[] ps this.GetType().GetProperties();
foreach (PropertyInfo p in ps)
{
    csv.Append(p.GetValue(this, null);
    csv.Append(",");
}
0 голосов
/ 27 января 2018

получение значений свойств из простого объекта класса ....

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 голосов
/ 20 декабря 2016
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);

Затем мы можем записать строку заметок в виде столбца в таблицу журнала или в файл. Вы должны использовать System.Reflection, чтобы использовать PropertyInfo

0 голосов
/ 23 февраля 2016
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);

Внимание: целевой объект должен быть настраиваемым

0 голосов
/ 25 ноября 2010

Цикл по свойствам

Type t = typeof(MyClass);
foreach (var property in t.GetProperties())
{                
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...