C # Itera attraverso le proprietà della classe


118

Attualmente sto impostando tutti i valori del mio oggetto di classe Record.

Questo è il codice che sto usando per popolare il record al momento, proprietà per proprietà.

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

Posso iterare dinamicamente attraverso ciascuna delle proprietà senza codificare tutti i nomi delle proprietà?

Qualcosa del genere:

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

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

1
Hai provato Reflection? stackoverflow.com/questions/997747/…
kol

1
dai un'occhiata a questo link stackoverflow.com/questions/721441/…
Enigma State

Potresti spiegare dove e come vorresti mantenere la relazione tra una proprietà e l'indice nell'array resultItems?
Erno

Risposte:


226

Potresti usare Reflection per farlo. Per quanto ne so, potresti enumerare le proprietà della tua classe e impostare i valori. Dovresti provarlo e assicurarti di aver compreso l'ordine delle proprietà. Fare riferimento a questa documentazione MSDN per ulteriori informazioni su questo approccio.

Per un suggerimento, potresti fare qualcosa del tipo:

Record record = new Record();

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

Dov'è valueil valore in cui vuoi scrivere (quindi dal tuo resultItemsarray).


1
E se volessi usare property.Getvalue (someOtherClassObjectHavingExacltySameProperties) invece di un valore ? (Ho provato questa proprietà? .SetValue (objAppointment, property.GetValue (temp)); ma mi dà {"L'oggetto non corrisponde al tipo di destinazione."} )
Asif Mehmood

@MalikAsif Non sono sicuro di aver capito appieno, ma sembra che tu stia cercando di caricare una proprietà di un tipo diverso. Se pubblichi una domanda su SO con un esempio e la colleghi qui, ti darò un'occhiata.
Samuel Slade,

1
Questo è un assoluto risparmio di vita - grazie! Sto iterando tutte le proprietà della classe per verificare di avere un valore (prima di scriverlo in XML)
Cordell

@Cordell, come hai fatto? Ho provato property.GetValue () ma richiede un oggetto come parametro.
user7792598

@ user7792598 È necessario passare l'oggetto da cui si desidera ottenere il valore della proprietà. Se hai bisogno di ulteriore aiuto, pubblica un'altra domanda 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
Sembra buono, ma speravo di farlo in modo dinamico, piuttosto che codificare i nomi dei campi lì dentro. È possibile? Grazie
Luke

Inoltre sembra che la GetPropertyproprietà non sia disponibile per la mia istanza di classe. : /
Luca

no, deve esserci una mappatura da qualche parte tra gli indici resultItem e i nomi delle proprietà.
jgauffin

1
@Coulton Come pensi di associare dinamicamente ogni proprietà a un indice? Non e possibile.
Amy

puoi provare nameof(Item.Field)invece di "itemtype"evitare l'hard coding di C # 6.0
Patrick Michaelsen

2

Sì, potresti creare un indicizzatore sulla tua classe Record che mappa dal nome della proprietà alla proprietà corretta. Ciò manterrebbe tutto il legame dal nome della proprietà alla proprietà in un unico posto, ad esempio:

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

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

In alternativa, come altri hanno già detto, usa la riflessione.


1

Ho provato quello che ha suggerito Samuel Slade . Non ha funzionato per me. La PropertyInfo lista stava diventando vuota. Quindi, ho provato quanto segue e ha funzionato per me.

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

1
Questo perché il tuo tipo ha solo campi, non proprietà !?
jamheadart
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.