Is there a general way to detect if a property's type is an enumerable type?
Given this:
class InvoiceHeader {
public int InvoiceHeaderId { get; set; }
IList<InvoiceDetail> LineItems { get; set; }
}
I'm currently using this cod开发者_JS百科e to detect if a class has a collection property:
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);
}
}
}
Is there a general way to detect if the LineItems is an enumerable type? Some will use other enumerable type (e.g. ICollection), not an IList.
Your code doesn't actually check if the properties are Enumerable
types but if they are generic IList's. Try this:
if(typeof(IEnumerable).IsAssignableFrom(p.PropertyType))
{
System.Windows.Forms.MessageBox.Show(p.Name);
}
Or this
if (p.PropertyType.GetInterfaces().Contains(typeof(IEnumerable)))
{
System.Windows.Forms.MessageBox.Show(p.Name);
}
if (invoiceHeader.LineItems is IEnumerable) {
// LineItems implements IEnumerable
}
This does not work if the type of the invoiceHeader is unknown at compile time. In that case I would like to know why there isn't a common interface, because the use of reflection to find a collection property is quite dubious.
IEnumerable is the base type for all Enumerable types in C#, and thus you can check for if a property is of that type generally.
It should however be noted that C# is special in the way it binds sugar syntax (e.g. foreach loop), that it binds to methods (so for a complete check you should check if a property contains a method called GetEnumerator (Either IEnumerable.GetEnumerator or IEnumerable.GetEnumerator)
p.PropertyType.IsGenericType
&& p.PropertyType.GetGenericTypeDefinition().Equals(typeof(ICollection<>))
This worked for me when using Entity Framework context.
精彩评论