Func 선언하기 역동적 인

anonymous-methods c# expression-trees lambda predicate

문제

이걸 고려하세요:

var propertyinfo = typeof(Customer).GetProperty(sortExpressionStr);
Type orderType = propertyinfo.PropertyType;

지금 나는 선언하고 싶다.

Func<int,orderType>

ordertype 이 런타임에 있기 때문에 직접적으로 불가능하다는 것을 알고 있지만 어떤 해결 방법이 있습니까?

이것이 바로 내가하고 싶은 일입니다.

var propertyinfo = typeof(T).GetProperty(sortExpressionStr);
Type orderType = propertyinfo.PropertyType;

var param = Expression.Parameter(typeof(T), "x");
var sortExpression = (Expression.Lambda<Func<T, orderType>>
   (Expression.Convert(Expression.Property(param, sortExpressionStr), typeof(orderType)), param));

이 모든 것은 다음과 같이 변환하고자하기 때문에 :

Expression<Func<T,object>> to Expression<Func<T,orderType>>

또는 불가능한 경우 올바른 유형의 첫 번째 위치에서 만들려는 경우 다음과 같은 경우입니다.

나는 type(Customer) 과 그것으로 주문하고자하는 타입의 프로퍼티 이름을 가진 메소드 안에 있는데, 정렬 식 트리를 생성하여 Orderby (여기)에 전달하려고합니다.

수락 된 답변

linqClass.OrderBy(GetSortExpression(sortstr));


public static Expression<Func<T,object>> GetSortExpression<T>(string sortExpressionStr)
    {
        var param = Expression.Parameter(typeof(T), "x");
        var sortExpression = Expression.Lambda<Func<T, object>>(Expression.Property(param, sortExpressionStr), param);
        return sortExpression;
    }

이 내 문제는 내가 추가 매개 변수를 Typeof (Object) 전달하는 데 사용되는 및 orderby 개체 유형별로 정렬 할 수 없다는 것을 말해 사용됩니다. 모두에게 감사합니다.

고마워 dtb 나는 당신의 대답이 너무 일하는지를 점검 할 것이고 만약 내가 성공한다면 받아 들일 것이다.


인기 답변

열려있는 제네릭 형식 정의를 사용하여이 작업을 수행 한 다음 해당 형식을 사용하여 특정 형식을 만들 수 있습니다.

typeof(Func<,>).MakeGenericType(typeof(int), orderType);

그러나, 당신이하려고하는 것은 ( Lambda<TDelegate> 호출하는 것) 직접 가능하지 않습니다. type 매개 변수없이 Lambda 를 호출해야합니다.

var propertyinfo = typeof(T).GetProperty(sortExpressionStr);
Type orderType = propertyinfo.PropertyType;

var param = Expression.Parameter(typeof(T), "x");
var sortExpression = Expression.Lambda(
        Expression.Convert(Expression.Property(param, sortExpressionStr),
                           orderType), 
        param));

이렇게하면 배경에 적합한 Func<,> 이 생성됩니다. 표현식을 컴파일하고 위임자를 사용하려면 다음과 같이 동적으로 만 수행하면됩니다.

sortExpression.Compile().DynamicInvoke(param);

Queryable 에서 OrderBy 확장 메소드를 호출하려는 경우 상황이 조금 복잡해집니다.

var propertyInfo = typeof(T).GetProperty(sortExpressionStr);
Type orderType = propertyInfo.PropertyType;

// first find the OrderBy method with no types specified
MethodInfo method = typeof(Queryable).GetMethods()
  .Where(m => m.Name == "OrderBy" && m.GetParameters().Length == 2)
  .Single();
// then make the right version by supplying the right types
MethodInfo concreteMethod = method.MakeGenericMethod(typeof(T), orderType);

var param = Expression.Parameter(typeof(T), "x");

// the key selector for the OrderBy method
Expression orderBy =
    Expression.Lambda(
        Expression.Property(orderParam, propertyInfo),
        orderParam);

// how to use:
var sequence = new T[0].AsQueryable(); // sample IQueryable

// because no types are known in advance, we need to call Invoke 
// through relection here
IQueryable result = (IQueryable) concreteMethod.Invoke(
                                   null, // = static
                                   new object[] { sequence, orderBy });


아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.