2014-03-05 48 views
0

我有一個自定義比較器,我想與OrderBy一起使用。我正在嘗試構建一個LINQ表達式來使其工作。所以實質上,我試圖將一個IComparer,OrderBy放入inLinq表達式中。LINQ中的自定義IComparer OrderBy Lambda表達式

我想建立應該是這個樣子的表達:

source => source.OrderBy(lambdaParameter => lambdaParameter.Name, new Parsers.NumericComparer()). 

隨着表達

'{source => source.OrderBy(lambdaParameter => lambdaParameter.Name)}' 

下面的代碼被編譯,我想這個自定義IComparable接口添加到這個表達式

new Parsers.NumericComparer(). 

這是因爲我需要做一個自然的排序。有人可以幫助我如何包含這個表達。我正在嘗試閱讀過去幾個小時的幾個主題,但我還沒有完全理解LINQ表達式,但尚未實現。謝謝!

private void CreateOrderByMethod(PropertyDescriptor prop, string orderByMethodName, string cacheKey) 
{ 
    /* 
    Create a generic method implementation for IEnumerable<T>. 
    Cache it. 
    */ 
    var sourceParameter = Expression.Parameter(typeof(List<T>), "source"); 
    var lambdaParameter = Expression.Parameter(typeof(T), "lambdaParameter"); 

    var accesedMember = typeof(T).GetProperty(prop.Name); 
    var propertySelectorLambda = 
     Expression.Lambda(Expression.MakeMemberAccess(lambdaParameter, accesedMember), lambdaParameter); 

    var orderByMethod = typeof(Enumerable).GetMethods() 
            .Where(a => a.Name == orderByMethodName && 
               a.GetParameters().Length == 2) 
            .Single() 
            .MakeGenericMethod(typeof(T), prop.PropertyType); 
    var orderByExpression = Expression.Lambda<Func<List<T>, IEnumerable<T>>>(
           Expression.Call(orderByMethod, 
             new Expression[] { sourceParameter, 
                 propertySelectorLambda }), 
             sourceParameter); 
    cachedOrderByExpressions.Add(cacheKey, orderByExpression.Compile()); 
} 

回答

0

要創建創建對象的新實例的表達,使用Expression.New

var newParser = Expression.New(typeof(Parsers.NumericComparer)); 

那麼我建議你使用的Expression.Call此重載代替,這樣你就不必去和手動搶的MethodInfo:

var orderByCall = Expression.Call(
    typeof(Enumerable), 
    "OrderBy", 
    new [] { typeof(T), prop.PropertyType }, 
    sourceParameter, propertySelectorLambda, newParser);