アイテムの配列で Contains を呼び出すラムダ式でジェネリック メソッドを呼び出す方法を探しています。
この場合、Entity Framework Where メソッドを使用していますが、シナリオは他の IEnumerables にも適用できます。
リフレクションを介して上記のコードの最後の行を呼び出す必要があるため、任意の型と任意のプロパティを使用して、Contains メソッドに渡すことができます。
var context = new TestEntities();
var items = new[] {100, 200, 400, 777}; //IN list (will be tested through Contains)
var type = typeof(MyType);
context.Set(type).Where(e => items.Contains(e.Id)); //**What is equivalent to this line using Reflection?**
研究では、GetMethod、MakeGenericType、および Expression を使用してそれを実現する必要があることに気付きましたが、その方法がわかりませんでした。リフレクションがラムダとジェネリックの概念でどのように機能するかを理解できるように、このサンプルがあると非常に役立ちます。
基本的に、目的は次のような関数の正しいバージョンを書くことです:
//Return all items from a IEnumerable(target) that has at least one matching Property(propertyName)
//with its value contained in a IEnumerable(possibleValues)
static IEnumerable GetFilteredList(IEnumerable target, string propertyName, IEnumerable searchValues)
{
return target.Where(t => searchValues.Contains(t.propertyName));
//Known the following:
//1) This function intentionally can't be compiled
//2) Where function can't be called directly from an untyped IEnumerable
//3) t is not actually recognized as a Type, so I can't access its property
//4) The property "propertyName" in t should be accessed via Linq.Expressions or Reflection
//5) Contains function can't be called directly from an untyped IEnumerable
}
//Testing environment
static void Main()
{
var listOfPerson = new List<Person> { new Person {Id = 3}, new Person {Id = 1}, new Person {Id = 5} };
var searchIds = new int[] { 1, 2, 3, 4 };
//Requirement: The function must not be generic like GetFilteredList<Person> or have the target parameter IEnumerable<Person>
//because the I need to pass different IEnumerable types, not known in compile-time
var searchResult = GetFilteredList(listOfPerson, "Id", searchIds);
foreach (var person in searchResult)
Console.Write(" Found {0}", ((Person) person).Id);
//Should output Found 3 Found 1
}
式がどのように機能するかを明確に理解できたとは思わないため、他の質問がこのシナリオに対応しているかどうかはわかりません。
アップデート:
実行時に (Contains で) テストするタイプとプロパティしかないため、ジェネリックを使用できません。最初のコード サンプルでは、コンパイル時に "MyType" が不明であるとします。2 番目のコード サンプルでは、型をパラメーターとして GetFilteredList 関数に渡すか、リフレクション (GetGenericArguments) を介して取得することができます。
ありがとう、