类似:Convert a string to Linq.Expressions or use a string as Selector?
类似的那个:Passing a Linq expression as a string?
另一个回答相同的问题:How to create dynamic lambda based Linq expression from a string in C#?
询问有这么多类似问题的事情的理由:
这些类似问题中接受的答案是不可接受的,因为它们都引用了4年前的一个库(授予它是由代码大师Scott Gu编写的)为旧框架(.net 3.5)编写的,并且不提供什么,但链接作为答案。
有一种方法可以在代码中执行此操作,而不包括整个库。
以下是此情况的示例代码:
public static void getDynamic<T>(int startingId) where T : class
{
string classType = typeof(T).ToString();
string classTypeId = classType + "Id";
using (var repo = new Repository<T>())
{
Build<T>(
repo.getList(),
b => b.classTypeId //doesn't compile, this is the heart of the issue
//How can a string be used in this fashion to access a property in b?
)
}
}
public void Build<T>(
List<T> items,
Func<T, int> value) where T : class
{
var Values = new List<Item>();
Values = items.Select(f => new Item()
{
Id = value(f)
}).ToList();
}
public class Item
{
public int Id { get; set; }
}
请注意,这并不是要将整个字符串转换为表达式,例如
query = "x => x.id == somevalue";
但是只是尝试仅使用字符串作为访问
query = x => x.STRING;
答案 0 :(得分:15)
这是表达式树的尝试。我仍然不知道这是否适用于Entity框架,但我认为值得一试。
Func<T, int> MakeGetter<T>(string propertyName)
{
ParameterExpression input = Expression.Parameter(typeof(T));
var expr = Expression.Property(input, typeof(T).GetProperty(propertyName));
return Expression.Lambda<Func<T, int>>(expr, input).Compile();
}
这样称呼:
Build<T>(repo.getList(), MakeGetter<T>(classTypeId))
如果您可以使用Expression<Func<T,int>>
代替Func
,只需删除对Compile
的调用(并更改MakeGetter
的签名)。< / p>
修改强>:
在评论中,TravisJ询问他如何使用它:w => "text" + w.classTypeId
有几种方法可以做到这一点,但为了便于阅读,我建议先引入一个局部变量,如下所示:
var getId = MakeGetter<T>(classTypeId);
return w => "text" + getId(w);
重点是吸气剂只是一个功能,你可以像往常一样使用它。像这样阅读Func<T,int>
:int DoSomething(T instance)
答案 1 :(得分:2)
以下是我的测试代码(linqPad)的扩展方法:
class test
{
public string sam { get; set; }
public string notsam {get; set; }
}
void Main()
{
var z = new test { sam = "sam", notsam = "alex" };
z.Dump();
z.GetPropertyByString("notsam").Dump();
z.SetPropertyByString("sam","john");
z.Dump();
}
static class Nice
{
public static void SetPropertyByString(this object x, string p,object value)
{
x.GetType().GetProperty(p).SetValue(x,value,null);
}
public static object GetPropertyByString(this object x,string p)
{
return x.GetType().GetProperty(p).GetValue(x,null);
}
}
结果:
答案 2 :(得分:1)
我没有试过这个,也不确定它是否会起作用,但你可以使用类似的东西:
b => b.GetType().GetProperty(classTypeId).GetValue(b, null);