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
リフレクションを試しましたか?stackoverflow.com/questions/997747/...
KOL

1
plsはこのリンクを見てください。stackoverflow.com
Enigma State

プロパティとresultItems配列のインデックス間の関係を維持する場所と方法を説明できますか?
Erno、

回答:


226

リフレクションを使用してこれを行うことができます。私が理解している限り、クラスのプロパティを列挙して値を設定できます。ただし、これを試してみて、プロパティの順序を理解しておく必要があります。このアプローチの詳細については、この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));しかし、{"オブジェクトがターゲットタイプと一致しません。"}
Asif Mehmood

@MalikAsif完全に理解したかどうかはわかりませんが、別のタイプからプロパティをロードしようとしているようです。例を挙げてSOに質問を投稿し、ここにリンクしていただければ、私が調査します。
Samuel Slade 2017年

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各プロパティを動的にインデックスに関連付けるにはどうすればよいですか?それは可能ではありません。
エイミー

C#6.0以降のハードコーディングを回避するnameof(Item.Field)代わりに試すことができます"itemtype"
Patrick Michaelsen

2

はい、プロパティ名から正しいプロパティにマップするRecordクラスにインデクサーを作成できます。これにより、プロパティ名からプロパティへのすべてのバインディングが1か所に保持されます。

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.