I have a method that looks like this:
private IEnumerable<T> QueryCollection<T>() where T : BaseObj
{
IEnumerable<T> items = query<T>();
return items;
}
I now have a situation where I want to filter this items collection IF the "T" supports a certain interface (it might not so i can't simply add it as a constraint of T). So i want something like this:
private IEnumerable<T> QueryCollection<T>() where T : BaseObj
{
IEnumerable<T> items = query<T>();
if (typeOf(T).GetInterface(ITeamFilterable) != null)
{
items = FilterByTeams(items);
}
return items;
}
What is the recommended way of checking if my generic Type supports a certain interface **and then if YES, then
NOTE: FilterByTeams takes in an:
IEnumerable<ITeamFilterable>
AND returns
IEnumerable<ITeamFilterable>
Do I need to cast the collection 2 times (one to convert to List of the interface and then again to convert back to list of T?)
I'm afraid you can't use is
/as
in this case unless you can start enumerating the query.
You can use reflection like that:
private IEnumerable<T> QueryCollection<T>() where T : BaseObj
{
IEnumerable<T> items = query<T>();
if (typeof(ITeamFilterable).IsAssignableFrom(typeof(T)))
items = (IEnumerable<T>)(object)FilterByTeams(items.Cast<ITeamFilterable>());
return items;
}
But if you can enumerate the query, you can do that to avoid reflection (assuming you have no null
items):
private IEnumerable<T> QueryCollection<T>() where T : BaseObj
{
IEnumerable<T> items = query<T>();
ICollection<T> itemsCollection = items as ICollection<T> ?? items.ToList();
if (itemsCollection.Count > 0)
{
var firstItem = itemsCollection.First();
if (firstItem is ITeamFilterable)
return (IEnumerable<T>)(object)FilterByTeams(itemsCollection.Cast<ITeamFilterable>());
}
return itemsCollection;
}
The casts will work since ITeamFilterable
is a T
and IEnumerable<T>
is covariant, but you have to cast to object
in-between to satisfy the generics constraints. Using these casts, there's no need to copy items around.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments