5

我有一个带有以下签名的排序扩展方法:

public static IEnumerable<T> CustomSort<T>(this IEnumerable<T> source, string sortProperties)

我们不久前写了它,它一直在做它的事情。现在我正在创建一个自定义控件,并且 DataSource 属性是一个 IEnumerable(非泛型)。有没有办法在非泛型 IEnumerable 中获取对象的类型?

我确信“对自定义控件数据源进行排序”的问题已经解决了一百万次,但我似乎无法找到解决方案。

4

3 回答 3

5

这里有一个基本问题,一个类型可以同时为多个 T 实现 IEnumerable-of-T。但如果我们排除这种情况,一个厚颜无耻的方法是:

void Evil<T>(IEnumerable<T> data) {...}

IEnumerable source = ...
dynamic cheeky = source;
Evil(cheeky);

这基本上将这个问题转移到了 DLR,让您的 Evil-of-T 方法轻松应对。

于 2012-12-02T09:37:42.673 回答
1

就个人而言,我只会使用

DataSource.Cast<object>()

然后你有一个IEnumerable<object>你可以在你的CustomSort<T>函数中使用的。我在这里假设这个函数已经可以处理任意对象;从第二个参数名称来看,我猜你无论如何都在使用反射,所以应该没问题。只需确保它GetType()在反映每个对象时使用它,而不是typeof(T),因为typeof(T)显然会使用object它并且它不会获得实际对象的字段列表。

当然,如果您在编译时实际上知道数据源中所有对象的类型,您可能希望使用该类型,例如:

DataSource.Cast<Customer>()
于 2012-12-02T09:08:41.863 回答
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});
    }

}
于 2012-12-02T10:04:53.850 回答