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
กรุณาดูที่ลิงค์นี้stackoverflow.com/questions/721441/…
Enigma State

คุณช่วยอธิบายได้ไหมว่าคุณต้องการรักษาความสัมพันธ์ระหว่างคุณสมบัติและดัชนีในอาร์เรย์ resultItems ที่ไหนและอย่างไร
Erno

คำตอบ:


226

คุณสามารถใช้ Reflection เพื่อทำสิ่งนี้ได้ เท่าที่ฉันเข้าใจคุณสามารถระบุคุณสมบัติของชั้นเรียนของคุณและตั้งค่าได้ คุณจะต้องลองใช้และตรวจสอบให้แน่ใจว่าคุณเข้าใจลำดับคุณสมบัติ อ้างอิงเอกสาร 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));แต่มันให้ฉัน{"Object ไม่ตรงกับประเภทเป้าหมาย"} )
Asif Mehmood

@MalikAsif ฉันไม่แน่ใจว่าฉันเข้าใจทั้งหมด แต่ดูเหมือนว่าคุณกำลังพยายามโหลดคุณสมบัติจากประเภทอื่น หากคุณโพสต์คำถามใน SO พร้อมตัวอย่างและเชื่อมโยงที่นี่ฉันจะตรวจสอบให้คุณ
Samuel Slade

1
นี่คือการช่วยชีวิตอย่างแท้จริง - ขอบคุณ! ฉันกำลังทำซ้ำคุณสมบัติคลาสทั้งหมดเพื่อตรวจสอบว่าฉันมีค่า (ก่อนที่จะเขียนเป็น XML)
Cordell

@ คอร์เดลล์คุณทำได้อย่างไร? ฉันลองใช้ property.GetValue () แต่มันขอออบเจ็กต์เป็นพารามิเตอร์
user7792598

@ 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คุณสมบัติดังกล่าวไม่มีให้สำหรับอินสแตนซ์คลาสของฉัน : /
ลุค

ไม่จำเป็นต้องมีการแมปที่ไหนสักแห่งระหว่างดัชนี resultItem และชื่อคุณสมบัติ
jgauffin

1
@ Coulton คุณคาดหวังที่จะเชื่อมโยงคุณสมบัติแต่ละรายการกับดัชนีแบบไดนามิกได้อย่างไร? มันเป็นไปไม่ได้.
Amy

คุณสามารถลองnameof(Item.Field)แทนที่จะ"itemtype"หลีกเลี่ยงการเข้ารหัสที่ยากใน C # 6.0
Patrick 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

ฉันลองทำตามที่Samuel Sladeแนะนำแล้ว ไม่ได้ผลสำหรับฉัน PropertyInfo รายการได้มาเป็นที่ว่างเปล่า ดังนั้นฉันลองทำสิ่งต่อไปนี้และได้ผลสำหรับฉัน

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

1
นั่นจะเป็นเพราะว่าประเภทของคุณมี แต่ช่องไม่ใช่คุณสมบัติ!?
jamheadart
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.