我有一个带有以下签名的排序扩展方法:
public static IEnumerable<T> CustomSort<T>(this IEnumerable<T> source, string sortProperties)
我们写了一段时间,它一直在做它的事情。现在我正在创建一个自定义控件,DataSource属性是一个IEnumerable(非泛型)。 有没有办法在非通用的IEnumerable中获取对象的类型?
我确信“排序自定义控件数据源”的问题已经解决了一百万次,但我似乎无法找到解决方案。
答案 0 :(得分:4)
这里有一个基本问题,一个类型可以同时为多个T实现IEnumerable-of-T。但如果我们排除这种情况,那么一种厚颜无耻的方法是:
void Evil<T>(IEnumerable<T> data) {...}
IEnumerable source = ...
dynamic cheeky = source;
Evil(cheeky);
这基本上将这个问题卸载到DLR,让你的Evil-of-T方法变得容易。
答案 1 :(得分:1)
就个人而言,我只会使用
DataSource.Cast<object>()
然后您可以在IEnumerable<object>
功能中使用CustomSort<T>
。我在这里假设这个函数已经可以处理任意对象了;根据第二个参数名称判断我猜你还在使用Reflection,所以应该没问题。只需确保它在反映时使用每个对象的GetType()
,而不是typeof(T)
,因为typeof(T)
显然会object
,并且它不会获得该字段的列表实际对象。
当然,如果您在编译时确实知道数据源中所有对象的类型,则可能需要使用该类型,例如:
DataSource.Cast<Customer>()
答案 2 :(得分:1)
您可以创建一个在运行时返回正确类型的扩展方法:
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;
}
}
更新:我添加了用于在非通用IEnumerable<T>
上执行特定于通用的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});
}
}