5

我有一个类型,它在实现IComparable<T>IComparable. 我没有从 LINQ 得到我期望的结果,基本上它看起来好像IComparable<T>没有应用类型实现的。

我想我会用以下形式的表达式得到我想要的结果:

var result = MyEnumerable<T>.OrderBy(r => r); 

whereT本身实现IComparable<T>. 它没有发生。

我可以看到IComparable<T>为排序指定了特定类的相关问题,但我找不到使用自身IComparable<T>实现的默认值的问题T

我的语法显然不正确。请问正确的语法是什么?

提前致谢。

4

2 回答 2

6

OrderBy使用默认比较器,而默认比较器Comparer<T>.Default将默认使用 for 的IComparable<T>实现,或者如果前者不存在T,则使用非泛型。IComparable

此代码有效:

public class Program
{
    static void Main(string[] args)
    {
        var list = new List<Stuff>
                       {
                           new Stuff("one"),
                           new Stuff("two"),
                           new Stuff("three"),
                           new Stuff("four")
                       };

        var sorted = list.OrderBy(x => x);

        foreach (var stuff in sorted)
        {
            Console.Out.WriteLine(stuff.Name);
        }
    }
}

public class Stuff : IComparable<Stuff>
{
    public string Name { get; set; }

    public Stuff(string name)
    {
        Name = name;
    }

    public int CompareTo(Stuff other)
    {
        return String.CompareOrdinal(Name, other.Name);
    }
}
于 2012-08-09T10:30:51.380 回答
1
public static class GenericSorter
{
    public static IOrderedEnumerable<T> Sort<T>(IEnumerable<T> toSort, Dictionary<string, SortingOrder> sortOptions)
    {
        IOrderedEnumerable<T> orderedList = null;

        foreach (KeyValuePair<string, SortingOrder> entry in sortOptions)
        {
            if (orderedList != null)
            {
                if (entry.Value == SortingOrder.Ascending)
                {
                    orderedList = orderedList.ApplyOrder<T>(entry.Key, "ThenBy");
                }
                else
                {
                    orderedList = orderedList.ApplyOrder<T>(entry.Key, "ThenByDescending");
                }
            }
            else
            {
                if (entry.Value == SortingOrder.Ascending)
                {
                    orderedList = toSort.ApplyOrder<T>(entry.Key, "OrderBy");
                }
                else
                {
                    orderedList = toSort.ApplyOrder<T>(entry.Key, "OrderByDescending");
                }
            }
        }

        return orderedList;
    }

    private static IOrderedEnumerable<T> ApplyOrder<T>(this IEnumerable<T> source, string property, string methodName)
    {
        ParameterExpression param = Expression.Parameter(typeof(T), "x");
        Expression expr = param;
        foreach (string prop in property.Split('.'))
        {
            expr = Expression.PropertyOrField(expr, prop);
        }
        Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T), expr.Type);
        LambdaExpression lambda = Expression.Lambda(delegateType, expr, param);

        MethodInfo mi = typeof(Enumerable).GetMethods().Single(
                method => method.Name == methodName
                        && method.IsGenericMethodDefinition
                        && method.GetGenericArguments().Length == 2
                        && method.GetParameters().Length == 2)
                .MakeGenericMethod(typeof(T), expr.Type);
        return (IOrderedEnumerable<T>)mi.Invoke(null, new object[] { source, lambda.Compile() });
    }
}
于 2012-11-21T00:17:14.263 回答