2014-03-05 2 views
0

OrderBy와 함께 사용하려는 사용자 지정 비교자를 가지고 있습니다. 내가 그것을 작동하게 LINQ 표현을 작성하려고합니다. 본질적으로, 나는 IComparer, OrderBy inLinq 표현식을 조합하려고합니다.LINQ의 사용자 지정 IComparer OrderBy 람다 식

내가 좋아하는 뭔가 보일 것입니다 구축을 위해 노력하고 표현 : 표현

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

아래의 코드로

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

내장하고 나는이 표현이 사용자 정의하여 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)); 

그럼 난 당신이 MethodInfo 가서 수동으로 잡아 필요가 없습니다 있도록, 대신 Expression.Call의이 오버로드를 사용하는 것이 좋습니다 :

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