2012-08-15 40 views
0

我有一个具有不同属性的上传类,我喜欢在此类中或其他属性中查找每个UploadObject属性。我如何在我的Upload类中找到所有UploadObjects?在对象中查找自定义类型

class UploadObject 
{ 
    public string ID {get; set;} 
    //... 
} 

class PicUpload 
{ 
    UploadObject Pic {get; set;} 
    //... 
} 

class FileUpload 
{ 
    UploadObject File {get; set;} 
    //... 
} 

class Upload 
{ 
    //.. 
    FileUpload File {get; set;} 
    List<PicUpload> Pics {get; set;} 
    //... 
    UploadObject Something {get; set} 
} 

编辑: 我在寻找像一个函数:

public object[] FindProperties(object objectTree, Type targetType) {} 
+0

你起始点的类的实例上传? – rene 2012-08-15 10:30:06

+0

@rene我已经更新了我的问题;-) – jwillmer 2012-08-15 10:41:54

+0

从你的'FindProperties'函数返回的数组包含什么? – PHeiberg 2012-08-15 11:11:20

回答

0

您正在寻找这样的事情?当返回类型是UploadClass或继承类

typeof(UploadClass).GetProperties().Where(x => x.PropertyType == typeof(UploadObject)); 
+0

@ Florlan07使用'Where(x => x.PropertyType == typeof(UploadObject))会不会更好;' – Willem 2012-08-15 10:32:18

+0

@Willem True,谢谢。 – oopbase 2012-08-15 11:03:01

2
typeof(Upload).GetProperties() 
    .Where(p => typeof(UploadObject).IsAssignableFrom(p.PropertyType)); 

将返回所有属性。然后你可以对它使用递归,并在不可能包含UploadObject的类型上使用停止条件。停止条件可以是使用IsPrimitive(可在Type上查看)来检查返回类型是否为原始类型。

如果您只是想要该特定类型,您可以用== typeof(UploadObject)替换IsAssignableFrom。

编辑:

这是想法,我的想法。免责声明:我所做的唯一测试是将其编译并针对一个场景运行,但它说明了这个想法。

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);