5

IComparable<T>and を実装するため、デフォルトのソート順を持つ型があります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がデフォルトで使用されます。前者が存在しない場合は、非ジェネリックが使用されます。IComparable<T>TIComparable

このコードは機能します:

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 に答える