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はObject型で並べ替えることができないことを教えてくれました。皆さんありがとう

ありがとうdtb私はあなたの答えが働くかどうかをチェックし、もしうまくいかなければ私はそれを受け入れます。


人気のある回答

開いているジェネリック型の定義を使用し、次にその中から特定の型を作ることでこれを行うことができます:

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

しかし、あなたがしようとしていること( Lambda<TDelegate>呼び出すこと)は直接的には不可能です。型パラメータなしで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);

QueryableOrderBy拡張メソッドを呼び出す場合は、少し複雑になります。

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は合法ですか? はい、理由を学ぶ