通用Linq订购功能?

时间:2009-06-08 18:49:10

标签: c# linq lambda

我希望能够传入Func< T,?>这允许我选择如何对项目列表进行排序...我遇到的问题是返回类型可能会有所不同......所以例如我想做这样的事情(不是生产代码):

Func<POline, string> poLineOrder
if (option) poLineOrder = poline => poline.PartNumber;
else poLineOrder = poline => poline.LineOrder;
var orderedLines = poLines.OrderBy(poLineOrder);

这里的问题是,虽然PartNumber是一个字符串,但LineOrder是一个int,并且此代码不能编译。我有一种感觉,我将不得不构建一个表达式(?),但我似乎无法正确的语法。

(是的,我可以通过使用poline.LineOrder.ToString(“D10”)解决这个问题,但我在这里问更一般的问题...谢谢!)

-mdb

2 个答案:

答案 0 :(得分:5)

OrderBy需要一个类型为Func<Item, Key>的键选择器函数和一个可选的IComparer<Key>来定义比较本身。

您需要以下帮助程序定义:

 class FunctorComparer<T> : IComparer<T> {
        private readonly Comparison<T> m_Comparison;

        public FunctorComparer(Comparison<T> Comparison) {
            this.m_Comparison = Comparison;
        }

        public int Compare(T x, T y) {
            return m_Comparison(x, y);
        }
    }

    static Comparison<TKey> Compare<TKey, TRes>(Func<TKey, TRes> Selector) where TRes : IComparable<TRes> {
        return (x, y) => Selector(x).CompareTo(Selector(y));
    }

现在你可以写

Comparison<POLine> x;

if (option) 
   x = Compare<POLine, int>(l => l.PartNumber);
else
   x = Compare<POLine, string>(l => l.LineOrder);

var res = poLines.OrderBy(i => i, new FunctorComparer<POLine>(x));

答案 1 :(得分:3)

您可能需要考虑使用Dynamic LINQ中的VS2008 Samples。然后你可以这样做:

var orderedLines = poLines.OrderBy( poLineOrder ? "PartNumber" : "LineOrder" );