首页 > 解决方案 > 如何确定列表类型的所有属性在一个对象中是空的还是空的?

问题描述

我有一个对象,它包含一些 int/string 属性和一些 List<T> 属性,其中 T 是项目本身中的一些其他类。有没有更简洁的方法来确定只有那些 List<T> 属性是空的还是空的?也许使用 Linq 语句?

我尝试搜索它,但找不到简短而干净的方法。我应该选择反思吗?有人可以提供与此相关的样本吗?

public class A
{
   ..some properties..
   List<ClassA> ListA { get; set; }
   List<ClassB> ListB { get; set; }
   List<ClassC> ListC { get; set; }
   List<ClassD> ListD { get; set; }
   ..some properties..
}

编辑1:到目前为止,我已经设法编写了一个干净的代码来检查列表属性是否为空。但是我如何检查它们是否为空。我需要将对象转换为 List 但我不知道 List 的类型

var matchFound = myObject.GetType().GetProperties()
                        .Where(x => x.PropertyType == typeof(List<>))
                        .Select(x => x.GetValue(myObject))
                        .Any(x => x != null);

编辑2:我最终使用了这个,一个工作正常的衬里:

var matchFound = myObject.GetType().GetProperties()
                        .Where(x =>(x.GetValue(myObject) as IList)?.Count()>0);

标签: c#

解决方案


这是我会做的。

    /// <summary>
    /// caching a Dyctionary of IList types for faster browsing
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    private static readonly Dictionary<Type, Type> CachedActualType = new Dictionary<Type, Type>();
    // Get Internal type of IList.
    // When the type is not a list then it will return the same type.
    // if type is List<T> it will return the type of T
    public static Type GetActualType(this Type type)
    {
        if (CachedActualType.ContainsKey(type))
            return CachedActualType[type];

        if (type.GetTypeInfo().IsArray)
            CachedActualType.Add(type, type.GetElementType());
        else if (type.GenericTypeArguments.Any())
            CachedActualType.Add(type, type.GenericTypeArguments.First());// this is almost always find the right type of an IList but if it fail then do the below. dont really remember why this fail sometimes.
        else if (type.FullName?.Contains("List`1") ?? false)
            CachedActualType.Add(type, type.GetRuntimeProperty("Item").PropertyType);
        else
            CachedActualType.Add(type, type);

        return CachedActualType[type];
    }

接着

var matchFound = myObject.GetType().GetProperties()
                        .Where(x => x.PropertyType.GetActualType() != x.PropertyType && 
                              (x.GetValue(myObject) as IList)?.Count()>0);

你实际上可以做得更好,不需要检查类型,只需尝试转换值。如果类型不是 IList,则该值将始终为 null

var matchFound = myObject.GetType().GetProperties()
                        .Where(x =>(x.GetValue(myObject) as IList)?.Count()>0);

推荐阅读