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
Ви спробували Reflection? stackoverflow.com/questions/997747/…
кол

1
pls перегляньте це посилання stackoverflow.com/questions/721441/…
Enigma State

Чи можете ви пояснити, де і як ви хочете підтримувати зв’язок між властивістю та індексом у масиві resultItems?
Ерно

Відповіді:


226

Ви можете, можливо, використовувати Reflection для цього. Наскільки я розумію, ви можете перерахувати властивості свого класу та встановити значення. Вам слід спробувати це і переконатися, що ви розумієте порядок властивостей. Для отримання додаткової інформації про цей підхід зверніться до цієї Документації MSDN .

Підказка, можливо, ви можете зробити щось на кшталт:

Record record = new Record();

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

Де valueзначення, яке ви хочете записати (так з вашого resultItemsмасиву).


1
Що робити, якщо я хочу використовувати value.Getvalue (someOtherClassObjectHavingExacltySameProperties) замість значення ? (Я спробував це властивість .SetValue (objAppointment, property.GetValue (температура)?); Але це дає мені, { "Об'єкт не відповідає цільової тип."} )
Асіф Mehmood

@MalikAsif Я не впевнений, що я повністю розумію, але це здається, що ви намагаєтеся завантажити властивість іншого типу. Якщо ви опублікуєте запитання на SO із прикладом і зв’яжете його тут, я буду шукати вас.
Самуель Слейд

1
Це абсолютна економія життя - дякую! Я перебираю всі властивості класу, щоб перевірити, чи є у мене значення (перед тим, як записати його в XML)
Cordell

@Cordell, як ти це зробив? Я спробував property.GetValue (), але він запитує об’єкт як параметр.
користувач7792598

@ user7792598 Вам потрібно передати об’єкт, від якого ви хочете отримати значення властивості. Якщо вам потрібна додаткова допомога, опублікуйте ще одне питання StackOverflow
Samuel Slade

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властивість недоступна для мого екземпляра класу. : /
Лука

ні, потрібно десь відображатись між індексами результатуІтем та назвами властивостей.
jgauffin

1
@Coulton Як ви очікуєте динамічно асоціювати кожну властивість до індексу? Це неможливо.
Емі

ви можете спробувати nameof(Item.Field)замість того, "itemtype"щоб уникнути жорсткого кодування станом на C # 6.0
Патрік Майклсен

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.