Есть ли общий способ определить, является ли тип свойства перечислимым типом?
Учитывая это:
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.
Ответы
Ответ 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)