ここでの「Name」と「Test_Result」は柔軟性があり、ハードコーディングできないと想定しています。
匿名型は完全に定義された通常のクラスです。それらについての唯一の興味深い点は、コンパイラがあなたの代わりに詳細を提供することです。
このシナリオを処理する方法は、Tuple.Create
を作成してそれらを、IEnumerable<Tuple<string,string>>
として参照することです(からの名前。他のオプションは、のようなものを使用してから、 APIまたはAPIのいずれかを使用することです。値を元に戻します。Item1
Item2
Tuple<,>
ExpandoObject
IDictionary<string,object>
dynamic
例えば:
string item1 = "Name";
string item2 = "Test_Result";
Type studentType = typeof(Student);
var itemParam = Expression.Parameter(studentType, "x");
var member1 = Expression.PropertyOrField(itemParam, item1);
var member2 = Expression.PropertyOrField(itemParam, item2);
var selector = Expression.Call(typeof(Tuple), "Create",
new[] { member1.Type, member2.Type }, member1, member2);
var lambda = Expression.Lambda<Func<Student, Tuple<string,string>>>(
selector, itemParam);
var currentItemFields = students.Select(lambda.Compile());
name
これは、メンバーとresult
:を使用したカスタムタイプへの同じ投影です。
class ProjectedData
{
public string name { get; set; }
public string result { get; set; }
}
...
string item1 = "Name";
string item2 = "Test_Result";
Type studentType = typeof(Student);
var itemParam = Expression.Parameter(studentType, "x");
var member1 = Expression.PropertyOrField(itemParam, item1);
var member2 = Expression.PropertyOrField(itemParam, item2);
var selector = Expression.MemberInit(Expression.New(typeof(ProjectedData)),
Expression.Bind(typeof(ProjectedData).GetMember("name").Single(), member1),
Expression.Bind(typeof(ProjectedData).GetMember("result").Single(), member2)
);
var lambda = Expression.Lambda<Func<Student, ProjectedData>>(
selector, itemParam);
var currentItemFields = students.Select(lambda.Compile());
または、辞書を使用したアプローチの場合:
string[] fields = {"Name", "Test_Result"};
Type studentType = typeof(Student);
var itemParam = Expression.Parameter(studentType, "x");
var addMethod = typeof(Dictionary<string, object>).GetMethod(
"Add", new[] { typeof(string), typeof(object) });
var selector = Expression.ListInit(
Expression.New(typeof(Dictionary<string,object>)),
fields.Select(field => Expression.ElementInit(addMethod,
Expression.Constant(field),
Expression.Convert(
Expression.PropertyOrField(itemParam, field),
typeof(object)
)
)));
var lambda = Expression.Lambda<Func<Student, Dictionary<string,object>>>(
selector, itemParam);
var currentItemFields = students.Select(lambda.Compile());