2010-11-25 2 views
45

Есть ли способ в C# перебрать свойства класса?Как вы можете перебрать свойства класса?

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

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

ответ

47

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

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(); 
} 
+0

спасибо за ответ, но есть сомнения reagarding доступа к свойствам другого класса, например: , если у меня есть `` List где бронирование класса, и `Cab`as другого класс и я ссылаться на него, как недвижимость в классе бронирования. как shud я разбираю через `foreach`, чтобы получить свойства класса Cab, а также ... Спасибо – Kulkarni 2013-01-17 07:02:58

+0

@sandy, что вы пробовали? – 2013-01-17 07:24:39

17
foreach (PropertyInfo prop in typeof(MyType).GetProperties()) 
{ 
    Console.WriteLine(prop.Name); 
} 
3

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

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

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

foreach (var property in properties) 
      { 
       here's code... 
      } 
0

это как цикл по свойствам в vb.net, его же понятие в C#, просто перевести синтаксис:

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

Looping над свойствами

Type t = typeof(MyClass); 
foreach (var property in t.GetProperties()) 
{     
} 
1

использовать что-то вроде

StringBuilder csv = String.Empty; 
PropertyInfo[] ps this.GetType().GetProperties(); 
foreach (PropertyInfo p in ps) 
{ 
    csv.Append(p.GetValue(this, null); 
    csv.Append(","); 
} 
1
var csv = string.Join(",",myObj 
    .GetType() 
    .GetProperties(BindingFlags.Public | BindingFlags.Instance) 
    .Select(p => p.GetValue(myObj, null).ToString()) 
    .ToArray()); 
4

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

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; (общедоступных).

0
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); 

для этого внимательно: целевого объекта должен быть setable

0
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

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

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++; 
     } 
    } 
} 
Смежные вопросы