你怎么能循环一个类的属性?
有没有办法在C#循环一个类的属性?
基本上我有一个包含大量属性的类(它基本上保存了大型数据库查询的结果)。 我需要输出这些结果作为一个CSV文件,所以需要将每个值附加到一个string。
它手动将每个值附加到一个string的显而易见的方式,但有没有办法有效地循环结果对象,并依次为每个属性添加值?
当然; 你可以在很多方面做到这一点; 从reflection开始(注意,这是缓慢的 – 尽pipe适量的数据虽然):
var props = objectType.GetProperties(); foreach(object obj in data) { foreach(var prop in props) { object value = prop.GetValue(obj, null); // against prop.Name } }
然而; 对于大量的数据来说,这样做会更有效率。 例如在这里,我使用Expression
API预编译一个委托,该委托看起来会写入每个属性 – 这里的优点是没有在每行的基础上进行reflection(对于大量的数据,这应该快得多):
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(); }
foreach (PropertyInfo prop in typeof(MyType).GetProperties()) { Console.WriteLine(prop.Name); }
我在这个页面上尝试了各种各样的build议,我无法完成任何工作。 我从最上面的答案开始(你会注意到我的variables被类似地命名),并且自己完成了它。 这是我的工作 – 希望它可以帮助别人。
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; (公共)属性。
你可以创build一个主题属性列表
IList<PropertyInfo> properties = typeof(T).GetProperties().ToList();
然后使用foreach导航到列表中..
foreach (var property in properties) { here's code... }
使用类似的东西
StringBuilder csv = String.Empty; PropertyInfo[] ps this.GetType().GetProperties(); foreach (PropertyInfo p in ps) { csv.Append(p.GetValue(this, null); csv.Append(","); }
var csv = string.Join(",",myObj .GetType() .GetProperties(BindingFlags.Public | BindingFlags.Instance) .Select(p => p.GetValue(myObj, null).ToString()) .ToArray());
这是如何循环在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
循环的属性
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);
意图:目标对象必须是setable
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);
然后,我们可以将笔记string作为列写入日志表或文件。 你必须使用System.Reflection来使用PropertyInfo