Reputation: 10561
I have a sorting extension method with the following signature:
public static IEnumerable<T> CustomSort<T>(this IEnumerable<T> source, string sortProperties)
We wrote it a while back and it has been doing its thing. Now I am creating a custom control and the DataSource property is an IEnumerable (non-generic). Is there any way to get the type of the objects in a non-generic IEnumerable?
I am sure the problem of "sort a custom control data source" has been solved a million times, but I just can't seem to find a solution.
Upvotes: 5
Views: 1553
Reputation: 6401
You could create an extension method that will return the correct type at runtime:
public static class LinqExtensions
{
public static Type GetElementType(this IEnumerable source)
{
var enumerableType = source.GetType();
if (enumerableType.IsArray)
{
return enumerableType.GetElementType();
}
if (enumerableType.IsGenericType)
{
return enumerableType.GetGenericArguments().First();
}
return null;
}
}
Update: I've added the mechanism that I would use to perform the generic-specific IEnumerable<T>
sorting on the non-generic IEnumerable
public static class SortingExtensions
{
public static IEnumerable<T> CustomSort<T>(this IEnumerable<T> source, string sortProperties)
{
// sort here
}
public static IEnumerable CustomSort(this IEnumerable source, string sortProperties)
{
var elementType = source.GetElementType();
var genericElementType = typeof (IEnumerable<>).MakeGenericType(elementType);
var sortMethod = typeof (SortingExtensions).GetMethod(
"CustomSort",
BindingFlags.Public | BindingFlags.Static,
null,
new [] {genericElementType, typeof (string)},
null);
return (IEnumerable) sortMethod.Invoke(null, new object[] {source, sortProperties});
}
}
Upvotes: 1
Reputation: 1062780
There is a fundamental issue here that a type can implement IEnumerable-of-T for multiple T at the same time. But if we exclude that case, a cheeky approach is:
void Evil<T>(IEnumerable<T> data) {...}
IEnumerable source = ...
dynamic cheeky = source;
Evil(cheeky);
This basically offloads this problem to the DLR, letting your Evil-of-T method take it easy.
Upvotes: 5
Reputation: 66573
Personally, I would just use
DataSource.Cast<object>()
and then you have an IEnumerable<object>
that you can use in your CustomSort<T>
function. I am assuming here that this function can handle arbitrary objects already; judging by the second parameter name I’m guessing that you’re using Reflection in it anyway, so it should be fine. Just make sure it uses each object’s GetType()
when reflecting on it, not typeof(T)
, because typeof(T)
will obviously be object
and it won’t get the list of fields of the actual object.
Of course, if you actually know the type of all the objects in the data source at compile-time, you might want to use that type instead, e.g.:
DataSource.Cast<Customer>()
Upvotes: 1