typeof(Upload).GetProperties()
.Where(p => typeof(UploadObject).IsAssignableFrom(p.PropertyType));
戻り型が UploadClass または継承クラスであるすべてのプロパティを返します。次に、UploadObject を含めることができないタイプの停止条件を使用して、再帰を使用する必要があります。IsPrimitive
停止条件は、 (available on )を使用して、戻り値の型がプリミティブ型であるかどうかを確認することType
です。
== typeof(UploadObject)
その特定のタイプが必要な場合は、 IsAssignableFrom を置き換えることができます。
編集:
これが私の考えたアイデアです。免責事項:私が行った唯一のテストは、それをコンパイルして1つのシナリオに対して実行することであり、それは機能しましたが、アイデアを示しています.
public static T[] GetAllPropertyValuesForTypeinTree<T>(object rootObject)
{
var propertyInfos = rootObject.GetType().GetProperties();
var withCorrectPropertyType = propertyInfos
.Where(p => p.PropertyType == typeof(T)).ToList();
var withListsOfType = propertyInfos.Where(p =>
IsEnumerableOf<T>(p.PropertyType)).ToList();
var complexProperties = propertyInfos.Except(
withCorrectPropertyType.Concat(withListsOfType))
.Where(p => !p.PropertyType.IsPrimitive && !p.PropertyType.IsGenericType);
var complexValues = new List<T>();
foreach (var complexProperty in complexProperties)
{
complexValues.AddRange(GetAllPropertyValuesForTypeinTree<T>(
complexProperty.GetValue(rootObject, null)));
}
var listValues = withListsOfType.Select(p =>
(IEnumerable)p.GetValue(rootObject, null))
.SelectMany(p => p.OfType<T>());
var propertyValues = withCorrectPropertyType.Select(p =>
(T) p.GetValue(rootObject, null));
return propertyValues.Concat(listValues).Concat(complexValues).ToArray();
}
private static bool IsEnumerableOf<T>(Type type)
{
if (!typeof (IEnumerable).IsAssignableFrom(type))
return false;
return type.GetInterfaces().Any(interfaceType => interfaceType.IsGenericType
&& (interfaceType.GetGenericTypeDefinition() == typeof(IEnumerable<>)
&& type.GetGenericArguments()[0] == typeof(T)))
|| type == typeof(IEnumerable<T>);
}
次のように呼び出します。
var propVals = GetAllPropertyValuesForTypeinTree<UploadObject>(theInstance);