简体   繁体   English

C# 遍历类属性

[英]C# Iterate through Class properties

I'm currently setting all of the values of my class object Record .我目前正在设置我的类对象Record所有值。

This is the code that I'm using to populate the record at the moment, property by property.这是我目前用来逐个属性地填充记录的代码。

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

Can I iterate through each of the properties dynamically without hard coding all of the property names?我可以在不硬编码所有属性名称的情况下动态迭代每个属性吗?

Something like so:像这样:

// Create new Record instance
Record newRecord = new Record();

for (int e = 0; e < propertyCount.Length - 1; e++)
{
    newRecord[fieldname] = resultItems[i - (fieldCount - e)];
}

You could possibly use Reflection to do this.你可以使用反射来做到这一点。 As far as I understand it, you could enumerate the properties of your class and set the values.据我了解,您可以枚举类的属性并设置值。 You would have to try this out and make sure you understand the order of the properties though.您必须尝试一下,并确保您了解属性的顺序。 Refer to this MSDN Documentation for more information on this approach.有关此方法的更多信息,请参阅此MSDN 文档

For a hint, you could possibly do something like:作为提示,您可能会执行以下操作:

Record record = new Record();

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

Where value is the value you're wanting to write in (so from your resultItems array).其中value是您要写入的值(因此来自您的resultItems数组)。

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

I tried what Samuel Slade has suggested.我尝试了塞缪尔·斯莱德 (Samuel Slade ) 的建议。 Didn't work for me.没有为我工作。 The PropertyInfo list was coming as empty. PropertyInfo列表是空的。 So, I tried the following and it worked for me.所以,我尝试了以下方法,它对我有用。

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

Yes, you could make an indexer on your Record class that maps from the property name to the correct property.是的,您可以在 Record 类上创建一个索引器,从属性名称映射到正确的属性。 This would keep all the binding from property name to property in one place eg:这会将所有从属性名称到属性的绑定保存在一个地方,例如:

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

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

Alternatively, as others have mentioned, use reflection.或者,正如其他人提到的,使用反射。

Adding to Samuel Slade's response for anyone who chooses that approach (which is excellent).添加到Samuel Slade对任何选择这种方法的人回应(这很好)。 Take into consideration two things:考虑两件事:

  1. GetProperties() only gives you a list of PUBLIC properties in your class. GetProperties() 只为您提供类中的 PUBLIC 属性列表。 (any PRIVATE ones will not be included). (任何私人的将不包括在内)。
  2. You should be aware that every property you call SetValue() on should have a setter method to do so, or else an ArgumentException will be thrown (ie: "The property's set accessor is not found").您应该知道,您调用 SetValue() 的每个属性都应该有一个 setter 方法来这样做,否则将抛出 ArgumentException(即:“未找到该属性的 set 访问器”)。

Having said that, special care with properties with no setter method like below:话虽如此,请特别注意没有 setter 方法的属性,如下所示:

public string Username { get; set; }
public bool HasCar
    {
        get
        {
            return this.Car != null;
        }
    }

Here the first property will be able to be set to the specified value but the second one not because it does not have a setter method.这里第一个属性将能够设置为指定的值,但第二个属性不能设置,因为它没有 setter 方法。 What I do to solve this is use GetSetMethod() over the properties to discriminate the ones with no setter methods like below:我为解决这个问题所做的是在属性上使用 GetSetMethod() 来区分那些没有 setter 方法的属性,如下所示:

var properties = this.GetType().GetProperties();
foreach(var prop in properties)
{
    if(prop.GetSetMethod() != null) {
        prop.SetValue(this, null);
    };
}

Hope this comment saves you some time!希望这条评论可以为您节省一些时间!

Cheers干杯

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM