有没有办法将不同的keySelectors返回到一个OrderBy?

时间:2012-02-21 17:35:24

标签: c# linq lambda

我的内线有OrderBy。这条线重复了几次,只有一点点差异:

OrderBy(m => m.Name)
OrderBy(m => m.CreationTime)

为了可维护性,有没有办法只生成一行,并让它调用某种方法,或者使用一些Action来处理返回正确的字段?问题是字段的类型不同。

4 个答案:

答案 0 :(得分:4)

看看这个方法签名:

  

public static IOrderedEnumerable OrderBy(       这个IEnumerable来源,       Func keySelector,       IComparer比较器   )

您需要提供IComparer<TKey>

data.OrderBy(x => x, new FooComparer());
data.OrderBy(x => x, new BarComparer());
data.OrderBy(x => x, new BazComparer());

不确定为排序创建类是否更清晰......

您还可以创建不同的方法,根据它们作为参数获得的枚举对列表进行排序 我认为这是一个更清洁的解决方案。

MSDN

答案 1 :(得分:1)

也许这更接近你想要的东西

public IComparable GetKey(int keyNum)
{
    switch (keyNum) {
        case 1:
            return Name;
        case 2:
            return CreationTime;
        default:
            return null;
    }
}

排序会像这样发生

.OrderBy(m => m.GetKey(1))

另一种方法是返回一个代表

public static Func<MyClass, IComparable> GetKeySelector(int keyNum)
{
    switch (keyNum) {
        case 1:
            return m => m.Name;
        case 2:
            return m => m.CreationTime;
        default:
            throw new ArgumentException();
    }
}

.OrderBy(MyClass.GetKeySelector(1));

答案 2 :(得分:0)

听起来你多次复制相同的整个选择?你只需要这个:

.OrderBy(m=>m.Name)
.ThenBy(m=>m.CreationTime);

答案 3 :(得分:0)

OrderBy之后,您必须使用ThenBy

.OrderBy(m => m.Name)
.ThenBy(m => m.CreationTime)

但这不能回答你的问题。在IComparable<Type_of_m>类型中实施m,然后您可以与

进行比较
.OrderBy(m => m)

class Type_of_m : IComparable<Type_of_m>
{
    public string Name { get; set; }
    public DateTime CreationTime { get; set; }

    public int CompareTo(Type_of_m other)
    {
        int comp = Name.CompareTo(other.Name);
        if (comp != 0) {
            return comp;
        }
        return CreationTime.CompareTo(other.CreationTime);
    }
}

如果您希望能够以多种方式订购商品,请使用Comparer作为gdoron 解释。这是嵌套类的一个很好的例子。

class MyClass
{
    public string Name { get; set; }
    public DateTime CreationTime { get; set; }

    public static readonly IComparer<MyClass> NameComparer = new MyNameComparaer();
    private class MyNameComparaer : IComparer<MyClass>
    {
        public int Compare(MyClass x, MyClass y)
        {
            return x.Name.CompareTo(y.Name);
        }
    }

    public static readonly IComparer<MyClass> DateComparer = new MyDateComparer();
    private class MyDateComparer : IComparer<MyClass>
    {
        public int Compare(MyClass x, MyClass y)
        {
            return x.CreationTime.CompareTo(y.CreationTime);
        }
    }
}

然后你可以这样订购

.OrderBy(m => m, MyClass.NameComparer)

或者像这样

.OrderBy(m => m, MyClass.DateComparer)