2010-11-25 32 views
45

¿Hay alguna manera en C# de recorrer las propiedades de una clase?¿Cómo se puede recorrer las propiedades de una clase?

Básicamente tengo una clase que contiene una gran cantidad de propiedades (básicamente contiene los resultados de una consulta de base de datos grande). Necesito dar salida a estos resultados como un archivo CSV, así que necesito anexar cada valor a una cadena.

La manera obvia de anexar manualmente cada valor a una cadena, pero ¿hay alguna manera de realizar un bucle efectivo sobre el objeto de resultados y agregar el valor para cada propiedad a su vez?

Respuesta

47

Claro; puedes hacer eso de muchas maneras; comenzando con la reflexión (obsérvese que esto es lento, aunque para cantidades moderadas de datos):

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

Sin embargo; para mayores volúmenes de datos, valdría la pena hacerlo más eficiente; por ejemplo, aquí uso la API Expression para precompilar un delegado que busca escribe cada propiedad; la ventaja aquí es que no se realiza ninguna reflexión por fila (esto debería ser significativamente más rápido para grandes volúmenes de datos):

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

gracias por la respuesta, pero tengo duda reagarding propiedades con el acceso de otra clase, como: si tengo '' Lista de las reservas es una clase, y 'Cab'as otra clase y que hacen referencia a él como una propiedad en la clase de reserva. cómo shud analizo a través del 'foreach' para obtener las propiedades de la clase Cab también ... Gracias – Kulkarni

+0

@sandy ¿qué has probado? –

+0

ryt ahora puedo obtener cada propiedad de la clase 'Booking', como ' foreach (var porp en obj2Insert) { // usando prop.GetValue() para devolver el resultado y almacenarlo. } ' ¡Pero esto atraviesa todas las propiedades de Booking Entity, que no necesito ...! ¡Aquí es donde me golpean ...! – Kulkarni

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

Usted puede hacer una lista de las propiedades de oject

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

y luego usar un foreach para navegar en la lista ..

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

esta es la forma de bucle sobre las propiedades en vb.net, es el mismo concepto en C#, simplemente traducir la sintaxis:

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

bucle sobre las propiedades

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

usar algo como

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

He intentado varias recomendaciones en esta página, no pude conseguir ninguna de ellas para trabajar. Comencé con la respuesta superior (notará que mis variables tienen un nombre similar), y la resolví por mi cuenta. Esto es lo que tengo que trabajar; espero que pueda ayudar a alguien más.

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 
     } 

*** Debo mencionar que esto solo funcionará si está utilizando get; set; propiedades (públicas)

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

attent para ello: objeto de destino debe ser setable

+0

Por favor, agrega una explicación. – OhBeWise

+0

@OhBeWisei han cambiado mi código, ahora no hay razón para la explicación – dewelloper

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

Podemos entonces escribir la cadena notas como una columna a la tabla de registro o en un archivo. Debe utilizar System.Reflection para utilizar PropertyInfo

0

obteniendo valores de propiedades del objeto de clase simple ....

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++; 
     } 
    } 
} 
Cuestiones relacionadas