C # Iterasi melalui properti Kelas

118

Saat ini saya menyetel semua nilai objek kelas saya Record.

Ini adalah kode yang saya gunakan untuk mengisi record saat ini, properti demi properti.

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

Dapatkah saya melakukan iterasi melalui setiap properti secara dinamis tanpa hard coding semua nama properti?

Sesuatu seperti itu:

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

for (int e = 0; e < propertyCount.Length - 1; e++)
{
    newRecord[fieldname] = resultItems[i - (fieldCount - e)];
}
Luke
sumber
1
Sudahkah Anda mencoba Refleksi? stackoverflow.com/questions/997747/…
kol
1
tolong lihat tautan ini stackoverflow.com/questions/721441/…
Enigma State
Bisakah Anda menjelaskan di mana dan bagaimana Anda ingin mempertahankan hubungan antara properti dan indeks dalam larik resultItems?
Erno

Jawaban:

226

Anda mungkin bisa menggunakan Refleksi untuk melakukan ini. Sejauh yang saya pahami, Anda dapat menghitung properti kelas Anda dan menetapkan nilainya. Anda harus mencobanya dan memastikan Anda memahami urutan propertinya. Lihat Dokumentasi MSDN ini untuk informasi lebih lanjut tentang pendekatan ini.

Sebagai petunjuk, Anda mungkin bisa melakukan sesuatu seperti:

Record record = new Record();

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

Di mana valuenilai yang ingin Anda tulis (jadi dari resultItemsarray Anda ).

Samuel Slade
sumber
1
Bagaimana jika saya ingin menggunakan property.Getvalue (someOtherClassObjectHavingExacltySameProperties) alih-alih nilai ? (Saya mencoba properti ini ? .SetValue (objAppointment, property.GetValue (temp)); tetapi memberi saya, {"Objek tidak cocok dengan jenis target."} )
Asif Mehmood
@ MalikAsif Saya tidak yakin saya sepenuhnya mengerti, tetapi sepertinya Anda mencoba memuat properti dari tipe yang berbeda. Jika Anda memposting pertanyaan tentang SO dengan contoh dan menautkannya di sini, saya akan mencari Anda.
Samuel Slade
1
Ini adalah penyelamat hidup mutlak - terima kasih! Saya mengulangi semua properti kelas untuk memeriksa apakah saya memiliki nilai (sebelum menulisnya ke XML)
Cordell
@ Cordell, bagaimana Anda melakukan itu? Saya mencoba property.GetValue () tetapi meminta objek sebagai parameter.
pengguna7792598
@ user7792598 Anda harus meneruskan objek yang ingin Anda dapatkan nilai propertinya. Jika Anda membutuhkan bantuan lebih lanjut, posting pertanyaan StackOverflow lainnya
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]);
}
jgauffin.dll
sumber
1
Ini terlihat bagus, tapi saya berharap untuk melakukannya secara dinamis, daripada mengkodekan nama field di sana. Apakah ini mungkin? Terima kasih
Lukas
Juga tampaknya GetPropertyproperti tidak tersedia untuk instance kelas saya. : /
Lukas
tidak, perlu ada pemetaan di suatu tempat antara indeks resultItem dan nama properti.
jgauffin
1
@Coulton Bagaimana Anda berharap untuk mengasosiasikan setiap properti ke indeks secara dinamis? Itu tidak mungkin.
Amy
Anda dapat mencoba nameof(Item.Field)alih-alih "itemtype"menghindari pengkodean keras pada C # 6.0
Patrick Michaelsen
2

Ya, Anda bisa membuat pengindeks di kelas Record Anda yang memetakan dari nama properti ke properti yang benar. Ini akan membuat semua pengikatan dari nama properti ke properti di satu tempat misalnya:

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

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

Sebagai alternatif, seperti yang disebutkan orang lain, gunakan refleksi.

Rich O'Kelly
sumber
1

Saya mencoba apa yang disarankan Samuel Slade . Tidak berhasil untuk saya. The PropertyInfo daftar datang sebagai kosong. Jadi, saya mencoba yang berikut dan berhasil untuk saya.

    Type type = typeof(Record);
    FieldInfo[] properties = type.GetFields();
    foreach (FieldInfo property in properties) {
       Debug.LogError(property.Name);
    }
BheemaSenan
sumber
1
Itu karena tipemu hanya memiliki bidang di atasnya, bukan properti !?
jamheadart