リフレクションを使用して配列を処理するにはどうすればいいですか?質問する

リフレクションを使用して配列を処理するにはどうすればいいですか?質問する

検証コードを書いています。このコードは、Web サービスに渡されたデータを取得し、アクションを実行できるかどうかを決定するか、呼び出し元にいくつかのフィールドが欠落しているなどのメッセージを返します。

配列を除いて、ほとんど機能しています。必須フィールドを表すために、[RequiredField]属性でプロパティをマークアップしています。これが私のデータの一部である場合、

public enum EnumTest
{
    Value1,
    Value2
}

[DataContract]
public class DummyWebserviceData
{
    [DataMember]
    [RequiredField]
    public EnumTest[] EnumTest{ get; set; }

    [DataMember]
    [RequiredField]
    public DummyWebserviceData2[] ArrayOfData { get; set; }
}

[DataContract]
public class DummyWebserviceData2
{
    [DataMember]
    [RequiredField]
    public string FirstName { get; set;}

    [DataMember]
    [RequiredField]
    public string LastName { get; set;}

    [DataMember]
    public string Description { get; set;}
}

では、何が機能しているのでしょうか? 日付と文字列の検証は機能しています。再帰を使用して、データに必要な任意のレベルの深さまで進みます。

しかし、そこにある 2 つの配列はどうでしょうか。1 つ目は列挙型の配列です。その場合、配列が空でないことを確認したいと思います。

2 番目は、DummyWebserviceData2 値の配列です。各値を取り出して個別に確認する必要があります。

私が書いたコードを簡略化すると次のようになります。

foreach (PropertyInfo propertyInfo in data.GetType().GetProperties())
{
    if (propertyInfo.PropertyType.IsArray)
    {
        // this craps out

        object[] array = (object[])propertyInfo.GetValue(data, new object[] { 0 });

    }
}

まず、それが配列であることがわかると思います。しかし、配列にいくつの項目があるかはどうすればわかるのでしょうか?

ベストアンサー1

実行時に、オブジェクトはArrayデータ型から動的にサブクラス化されます(このMSDNトピックでは、) なので、配列に反映する必要はなく、 をobjectにキャストしてArrayArray.GetValueインスタンス メソッドを使用できます。

Array a = (Array)propertyInfo.GetValue(data);
for(int i = 0; i< a.Length; i++)
{
  object o = a.GetValue(i);
}

.Net 2.0 以降では、配列を反復処理することもできます。

.NET Framework バージョン 2.0 では、Array クラスは System.Collections.Generic::IList、System.Collections.Generic::ICollection、および System.Collections.Generic::IEnumerable ジェネリック インターフェイスを実装します。

を知る必要はありませんT。これらから IEnumerable を取得でき、それに対して Cast() 操作を使用したり、 レベルで操作したりできるからですobject

ちなみに、コードが機能しない理由は、 がの基本型ではないため の配列をMyType[]にキャストできず、 のみであるためです。object[]object[]MyType[]object

おすすめ記事