Odbicie do wywołania metody ogólnej z parametrem wyrażenia lambda
Szukam sposobu na wywołanie metody ogólnej z wyrażeniem lambda, które wywołuje zawiera tablicę elementów.
W tym przypadku używam metody Entity Framework Where, ale scenariusz może być zastosowany w innych IEnumerables.
Muszę wywołać ostatni wiersz powyższego kodu poprzez Reflection, więc mogę użyć dowolnego typu i dowolnej właściwości, aby przejść do metody 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?**
W badaniach zauważyłem, że powinienem użyć GetMethod, MakeGenericType i Expression, aby to osiągnąć, ale nie mogłem się dowiedzieć, jak to zrobić. Bardzo pomocne byłoby posiadanie tego przykładu, aby zrozumieć, jak działa Reflection z koncepcjami Lambda i Generic.
Zasadniczo celem jest napisanie poprawnej wersji takiej funkcji:
//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
}
Nie jestem pewien, czy inne pytania dotyczą tego scenariusza, ponieważ nie sądzę, bym mógł jasno zrozumieć, jak działają wyrażenia.
Aktualizacja:
Nie mogę używać Generics, ponieważ mam tylko typ i właściwość do przetestowania (w Contains) w czasie wykonywania. W pierwszym przykładzie kodu przypuśćmy, że „MyType” nie jest znany w czasie kompilacji. W drugim przykładzie kodu typ może zostać przekazany jako parametr do funkcji GetFilteredList lub może być otrzymany poprzez Reflection (GetGenericArguments).
Dzięki,