C# 遍历类属性
Posted
技术标签:
【中文标题】C# 遍历类属性【英文标题】:C# Iterate through Class properties 【发布时间】:2011-12-30 09:57:17 【问题描述】:我目前正在设置我的类对象 Record
的所有值。
这是我目前用来逐个属性地填充记录的代码。
// Loop through each field in the result set
for (int i = 0; i <= resultItems.Length; i++)
Record newRecord = new Record()
itemtype = resultItems[i - (fieldCount - 0)],
itemdesc = resultItems[i - (fieldCount - 1)],
prodcode = resultItems[i - (fieldCount - 2)],
proddesc = resultItems[i - (fieldCount - 3)],
curstat = resultItems[i - (fieldCount -4)],
totfree = resultItems[i - (fieldCount -5)],
totphys = resultItems[i - (fieldCount -6)],
pcolgroup = resultItems[i - (fieldCount -7)],
scolgroup = resultItems[i - (fieldCount -8)],
totpo = resultItems[i - (fieldCount - 9)],
totso = resultItems[i - (fieldCount - 10)],
quality = resultItems[i - (fieldCount - 11)],
statusdesc = resultItems[i - (fieldCount - 12)],
groupcode = resultItems[i - (fieldCount - 13)],
qualitydes = resultItems[i - (fieldCount - 14)],
pcoldesc = resultItems[i - (fieldCount - 15)],
scoldesc = resultItems[i - (fieldCount - 16)],
pgroupdesc = resultItems[i - (fieldCount - 17)],
;
我能否在不对所有属性名称进行硬编码的情况下动态迭代每个属性?
类似这样的:
// Create new Record instance
Record newRecord = new Record();
for (int e = 0; e < propertyCount.Length - 1; e++)
newRecord[fieldname] = resultItems[i - (fieldCount - e)];
【问题讨论】:
你试过反射吗? ***.com/questions/997747/… 请看一下这个链接***.com/questions/721441/… 您能否解释一下您希望在何处以及如何维护属性与 resultItems 数组中的索引之间的关系? 【参考方案1】:您可以使用反射来执行此操作。据我了解,您可以枚举类的属性并设置值。您必须尝试一下,并确保您了解属性的顺序。有关此方法的更多信息,请参阅此MSDN Documentation。
作为提示,您可以执行以下操作:
Record record = new Record();
PropertyInfo[] properties = typeof(Record).GetProperties();
foreach (PropertyInfo property in properties)
property.SetValue(record, value);
value
是您要写入的值(因此来自您的 resultItems
数组)。
【讨论】:
如果我想使用 property.Getvalue(someOtherClassObjectHavingExacltySameProperties) 而不是 value 怎么办? (我试过这个 property?.SetValue(objAppointment, property.GetValue(temp)); 但它给了我,"Object does not match target type.") @MalikAsif 我不确定我是否完全理解,但听起来您正在尝试从不同类型加载属性。如果您通过示例发布关于 SO 的问题并将其链接到此处,我会为您查找。 这绝对是救生员 - 谢谢!我正在遍历所有类属性以检查我是否有一个值(在将其写入 XML 之前) @Cordell,你是怎么做到的?我试过 property.GetValue() 但它要求一个对象作为参数。 @user7792598 您需要传入要从中获取属性值的对象。如果您需要进一步的帮助,请发布另一个 *** 问题【参考方案2】:// the index of each item in fieldNames must correspond to
// the correct index in resultItems
var fieldnames = new []"itemtype", "etc etc ";
for (int e = 0; e < fieldNames.Length - 1; e++)
newRecord
.GetType()
.GetProperty(fieldNames[e])
.SetValue(newRecord, resultItems[e]);
【讨论】:
这看起来不错,但我希望动态进行,而不是在其中对字段名进行硬编码。这可能吗?谢谢 另外,GetProperty
属性似乎不适用于我的类实例。 ://
不,resultItem 索引和属性名称之间需要有一个映射。
@Coulton 您希望如何将每个属性与索引动态关联?这是不可能的。
你可以尝试nameof(Item.Field)
而不是"itemtype"
来避免C# 6.0的硬编码【参考方案3】:
是的,您可以在 Record 类上创建一个索引器,将属性名称映射到正确的属性。这会将所有从属性名称到属性的绑定保存在一个地方,例如:
public class Record
public string ItemType get; set;
public string this[string propertyName]
set
switch (propertyName)
case "itemType":
ItemType = value;
break;
// etc
或者,正如其他人所提到的,使用反射。
【讨论】:
【参考方案4】:我尝试了 Samuel Slade 的建议。没有为我工作。 PropertyInfo
清单是空的。所以,我尝试了以下方法,它对我有用。
Type type = typeof(Record);
FieldInfo[] properties = type.GetFields();
foreach (FieldInfo property in properties)
Debug.LogError(property.Name);
【讨论】:
那是因为你的类型只有字段,没有属性!? 如果我们必须获取属性值而不是设置 em 怎么办?【参考方案5】:添加到 Samuel Slade 的 对任何选择该方法的人的回应(这非常好)。考虑两点:
-
GetProperties() 只为您提供类中的 PUBLIC 属性列表。 (不包括任何私人的)。
您应该知道,您调用 SetValue() 的每个属性都应该有一个 setter 方法来执行此操作,否则将引发 ArgumentException(即:“找不到该属性的 set 访问器”)。
话虽如此,请特别注意没有设置方法的属性,如下所示:
public string Username get; set;
public bool HasCar
get
return this.Car != null;
这里第一个属性可以设置为指定值,但第二个不是因为它没有 setter 方法。我要解决这个问题是在属性上使用 GetSetMethod() 来区分没有如下设置方法的属性:
var properties = this.GetType().GetProperties();
foreach(var prop in properties)
if(prop.GetSetMethod() != null)
prop.SetValue(this, null);
;
希望这条评论能为您节省一些时间!
干杯
【讨论】:
以上是关于C# 遍历类属性的主要内容,如果未能解决你的问题,请参考以下文章
《C#零基础入门之百识百例》(八十七)系统类HasTable哈希表解析 -- 几种遍历方式