8

IQueryable <T>ソースがあり、IQueryable <T> .Count()を動的に呼び出したい。

したがって、IQueryableで宣言されたCountメソッドのMethodInfoが必要です。

これは、msdnからの(IQueryable <>内の)署名です。

public static int Count<TSource>(
    this IQueryable<TSource> source
)

これは私がどこまで得たかです:

Expression expr; //this is expression which holds my IQueryable<T>
MethodInfo mi = expr.Type.GetMethod("Count", BindingFlags.Static | BindingFlags.Public, null, new[] { expr.Type }, null); 

しかし、私のmiは常にnullです。

私も試しました:

mi = typeof(IQueryable<>).GetMethod("Count", BindingFlags.Static | BindingFlags.Public, null, new[] { expr.Type }, null);

しかし、再びnull。

私の最終的な目標は次のとおりです。

Expression.Call(mi, expr);

更新:これは私がSumExtensionメソッドを取得する方法です:

MethodInfo sum = typeof(Queryable).GetMethod("Sum", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(IQueryable<decimal>) }, null);

これは機能しますが、このSumメソッドはジェネリックではありません。静的ですが。

4

2 に答える 2

9

IQueryable<T>タイプの一般的な引数を取り除いて、それを使用する必要があります。また、メソッドを所有する型はそうではありませんIQueryable<T>、それはQueryable-あなたがそれについて考えるならば-インターフェースは静的メソッドを持つことができません(まあ、コメント者が指摘したように、C#ではそうです):)。

また、これはジェネリックメソッドであるため、試した方法でパラメーターを一致させることはできません。ジェネリックや実際の式ではなく、ジェネリック型の定義を渡す必要があるためです。 IQuerable<TSource> IQueryable<int>

Queryable代わりに、次のタイプで「Count」と呼ばれる静的メソッドの単一パラメーターバージョンを探すことができます。

Type genericArgument = expr.GetGenericArguments()[0];

MethodInfo countMethod = typeof(Queryable)
              .GetMethods(BindingFlags.Static | BindingFlags.Public)
              //narrow the search before doing 'Single()'
              .Single(mi => mi.Name == "Count"
                         // this check technically not required, but more future proof
                         && mi.IsGenericMethodDefinition
                         && mi.GetParameters().Length == 1)
              .MakeGenericMethod(genericArgument);

//now you can bind to 'countMethod'

2017年3月7日更新-明らかに、元のバージョンのコード例が機能しなくなったフレームワークの変更-これは機能するはずの更新バージョンです

もう少し詳しく説明します。メソッドのシグネチャは次のとおりです。

public static int Count<TSource>(
  this IQueryable<TSource> source
)

したがって、パラメータタイプはタイプIQueryable<TSource>よりも一般的ですが、式を調べて一般的な引数を取得するTSource必要がある理由です。IQueryable<TSource>また、ここでパラメーターについて私が何を意味するかを確認できるはずです。

于 2012-04-23T08:29:21.563 に答える
3

コンパイラにメソッドを取得させます。

Type genericArgument = expr.GetGenericArguments()[0];
var fakeExp = (Expression<Func<IQueryable<int>, int>>)(q => q.Count());
var mi = ((MethodCallExpression)fakeExp.Body).Method.GetGenericMethodDefinition().MakeGenericMethod(genericArgument);
于 2014-06-04T20:05:45.723 に答える