私はリフレクションを使用して少し作業をしており、List<T>
コレクションに対して実行できるLambdaExpressionを作成し、一致するものを見つけるためにHashSet<int>
コレクションと交差します。パラメータがLambdaExpressionをコンパイルするときに範囲外
私の問題は、T
は共通の基底クラスまたはインターフェイスを実装していないため、型と要件tpの反映によってプログラムでラムダ式が構築されていることです。
I'fは、私は自分のタイプを知っていた、私が実行するwnatことです:
List<TestClass> entityList = GetOriginalList();
HashSet<int> idList = new HashSet<int>() { 1, 2, 3, 4 };
List<TestClass> filteredList = entityList.Where(o => idList.Contains(o.Id)).ToList();
私はLambdaExpression
を使ってこれを行う方法をあざける始めたが、私はコンパイルするものを取得することができないことができますそれが何をしたいのかを理解しているようです(つまり、HashSet<int>
の変数を入力してください)。私の身体的な試みは以下の通りです。LambdaExpression
をコンパイルする方法と、もう一方の端にあるList<myObject>
を実際にどのように実行するのかについての提案はありますか?
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
namespace PoCDynamicLambda
{
class Program
{
class TestClass
{
private int _id;
private string _value;
public int Id { get { return this._id; } set { this._id = value; } }
public string Value { get { return this._value; } set { this._value = value; } }
public TestClass(int id, string value)
{
this._id = id;
this._value = value;
}
}
static void Main(string[] args)
{
List<TestClass> entityList = new List<TestClass>()
{
new TestClass(1, "One"),
new TestClass(2, "Two"),
new TestClass(3, "Three")
};
HashSet<int> idList = new HashSet<int>() { 2, 3, 5 };
MethodInfo containsMethod = idList.GetType().GetMethod("Contains");
ParameterExpression idListParam = Expression.Parameter(idList.GetType(), "idList");
ParameterExpression objectListParam = Expression.Parameter(typeof(TestClass), "entityList");
PropertyInfo idProperty = typeof(TestClass).GetProperty("Id");
MemberExpression idMember = Expression.Property(objectListParam, idProperty);
MethodCallExpression methodCall = Expression.Call(idListParam, containsMethod, idMember);
LambdaExpression le = Expression.Lambda(methodCall, objectListParam);
Console.WriteLine(le); // returns {entityList => idList.Contains(entityList.Id)}
le.Compile(); // Error here
Console.WriteLine(le.Compile().DynamicInvoke(entityList));
Console.ReadLine();
}
}
}
ありがとうございます!
うわー、あなたはすごいです!私は明日にログインして、誰かが答えたかどうかを見ています:) – mnield
だから、それは別のParameterExpressionと同じでしょうか?確かに、最終版では一定ではありません。 – mnield
@mnield - あなたはすでにパラメータ式を持っています。あなたはちょうど 'ラムダ 'の呼び出しにそれを含めなかった。これは 'Expression.Lambda(methodCall、objectListParam、idList)'(またはその逆)にする必要があります。同様に、呼び出すために*実際のリストを渡す必要があります: '.DynamicInvoke(entityList、idList)' –