Подтвердить что ты не робот

Есть ли общий способ определить, является ли тип свойства перечислимым типом?

Учитывая это:

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.

4b9b3361

Ответ 1

Ваш код фактически не проверяет, являются ли свойства Enumerable, но если они являются стандартными IList. Попробуйте следующее:

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

Или это

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

Ответ 2

if (invoiceHeader.LineItems is IEnumerable) {
    // LineItems implements IEnumerable
}

Это не работает, если тип invoiceHeader неизвестен во время компиляции. В этом случае я хотел бы знать, почему нет общего интерфейса, потому что использование отражения для поиска свойства коллекции довольно сомнительно.

Ответ 3

IEnumerable является базовым типом для всех типов Enumerable в С#, и, таким образом, вы можете проверить, является ли свойство этого типа вообще.

Следует, однако, отметить, что С# является особенным в том, как он связывает синтаксис сахара (например, цикл foreach), который он связывает с методами (поэтому для полной проверки вы должны проверить, содержит ли свойство метод GetEnumerator (либо IEnumerable.GetEnumerator или IEnumerable.GetEnumerator)