是否有一种通用的方法来检测属性';s类型是可枚举类型

本文关键字:类型 属性 检测 枚举 方法 一种 是否 | 更新日期: 2023-09-27 18:00:19

给定条件:

class InvoiceHeader {
    public int InvoiceHeaderId { get; set; }
    IList<InvoiceDetail> LineItems { get; set; }
}

我目前正在使用此代码来检测类是否具有集合属性:

void DetectCollection(object modelSource)
{       
    Type modelSourceType = modelSource.GetType();
    foreach (PropertyInfo p in modelSourceType.GetProperties())
    {
        if (p.PropertyType.IsGenericType &&  p.PropertyType.GetGenericTypeDefinition() == typeof(IList<>))
        {
            System.Windows.Forms.MessageBox.Show(p.Name);
        }
    }
}

是否有检测LineItems是否为可枚举类型的通用方法?有些将使用其他可枚举类型(例如ICollection),而不是IList。

是否有一种通用的方法来检测属性';s类型是可枚举类型

您的代码实际上并不检查属性是否为Enumerable类型,而是检查它们是否为泛型IList。试试这个:

if(typeof(IEnumerable).IsAssignableFrom(p.PropertyType))
{
   System.Windows.Forms.MessageBox.Show(p.Name);
}

或者这个

if (p.PropertyType.GetInterfaces().Contains(typeof(IEnumerable)))
{
    System.Windows.Forms.MessageBox.Show(p.Name);
}
if (invoiceHeader.LineItems is IEnumerable) {
    // LineItems implements IEnumerable
}

如果invoiceHeader的类型在编译时未知,则此操作不起作用。在这种情况下,我想知道为什么没有公共接口,因为使用反射来查找集合属性是非常可疑的。

IEnumerable是C#中所有可枚举类型的基类型,因此您可以检查属性是否通常属于该类型。

然而,应该注意的是,C#的特殊之处在于它绑定糖语法的方式(例如foreach循环),它绑定到方法(因此,为了进行完整的检查,您应该检查属性是否包含名为GetEnumerator的方法(IEnumerable.GetEnumerator或IEnumeraable.GetEn枚举器)

p.PropertyType.IsGenericType
    && p.PropertyType.GetGenericTypeDefinition().Equals(typeof(ICollection<>))

这在使用实体框架上下文时对我有效。