C#遍历类属性


118

我目前正在设置类对象的所有值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)];
}

1
您是否尝试过反射?stackoverflow.com/questions/997747/…–
kol


您能解释一下在什么地方以及如何保持resultItems数组中的属性与索引之间的关系吗?
Erno

Answers:


226

您可以使用反射来做到这一点。据我了解,您可以枚举类的属性并设置值。您必须尝试一下,并确保您了解属性的顺序。有关此方法的更多信息,请参考此MSDN文档

作为提示,您可以执行以下操作:

Record record = new Record();

PropertyInfo[] properties = typeof(Record).GetProperties();
foreach (PropertyInfo property in properties)
{
    property.SetValue(record, value);
}

value您要写入的值在哪里(因此来自resultItems数组)。


1
如果我想使用property.Getvalue(someOtherClassObjectHavingExacltySameProperties)而不是怎么办?(我想这个属性.SetValue(objAppointment,property.GetValue(TEMP));但它给了我,{ “对象不匹配目标类型。”}
阿西夫马哈茂德

@MalikAsif我不确定我是否完全理解,但听起来您正在尝试从其他类型加载属性。如果您通过示例发布关于SO的问题并在此处链接,我将为您寻找。
塞缪尔·斯莱德

1
这绝对是救命稻草-谢谢!我正在遍历所有类的属性以检查是否有一个值(在将其写入XML之前)
Cordell

@Cordell,您是怎么做到的?我尝试了property.GetValue(),但它要求一个对象作为参数。
user7792598

@ user7792598您需要传入要从中获取属性值的对象。如果您需要进一步的帮助,张贴其他StackOverflow的问题
塞缪尔·斯莱德

17
// 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]);
}

1
这看起来不错,但我希望动态地做到这一点,而不是硬编码其中的字段名。这可能吗?谢谢
路加福音

同样,该GetProperty属性似乎不适用于我的类实例。:/
路加福音

是的,在resultItem索引和属性名称之间需要某种映射。
jgauffin

1
@Coulton您如何期望将每个属性动态关联到索引?那不可能
艾米(Amy)

你可以尝试nameof(Item.Field),而不是"itemtype"避免硬编码为C#6.0
帕特里克Michaelsen

2

是的,您可以在Record类上创建一个索引器,该索引器从属性名称映射到正确的属性。这会将所有从属性名称到属性的绑定都放在一个位置,例如:

public class Record
{
    public string ItemType { get; set; }

    public string this[string propertyName]
    {
        set
        {
            switch (propertyName)
            {
                case "itemType":
                    ItemType = value;
                    break;
                    // etc
            }   
        }
    }
}

另外,正如其他人提到的那样,请使用反射。


1

我尝试了塞缪尔·斯莱德的建议。没为我工作。该PropertyInfo 名单来为空。因此,我尝试了以下方法,并且对我有用。

    Type type = typeof(Record);
    FieldInfo[] properties = type.GetFields();
    foreach (FieldInfo property in properties) {
       Debug.LogError(property.Name);
    }

1
那是因为您的类型上只有字段,没有属性!
jamheadart
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.