検証コードを書いています。このコードは、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
にキャストしてArray
、Array.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