我正在学习C#中的表达式树.
我现在被困了一段时间了:
string filterString = "ruby";
Expression<Func<string, bool>> expression = x => x == filterString;
Run Code Online (Sandbox Code Playgroud)
如何通过代码构造此表达式?没有示例如何捕获局部变量.这个很简单:
Expression<Func<string, bool>> expression = x => x == "ruby";
Run Code Online (Sandbox Code Playgroud)
这将是:
ParameterExpression stringParam = Expression.Parameter(typeof(string), "x");
Expression constant = Expression.Constant("ruby");
BinaryExpression equals = Expression.Equal(stringParam, constant);
Expression<Func<string, bool>> lambda1 =
Expression.Lambda<Func<string, bool>>(
equals,
new ParameterExpression[] { stringParam });
Run Code Online (Sandbox Code Playgroud)
调试器为(x => x == filterString)打印以下内容:
{x =>(x == value(Predicate.Program + <> c__DisplayClass3).filterString)}
感谢您对此主题有所了解.
可能重复:
查找传递给C#中函数的变量名称
在C#中,有没有办法(更好的方法)在运行时解析参数的名称?
例如,在以下方法中,如果重命名方法参数,则还必须记住更新传递给ArgumentNullException的字符串文字.
public void Woof(object resource)
{
if (resource == null)
{
throw new ArgumentNullException("resource");
}
// ..
}
Run Code Online (Sandbox Code Playgroud) 我有兴趣以重构安全的方式在运行时检索局部变量(和参数)的名称.我有以下扩展方法:
public static string GetVariableName<T>(Expression<Func<T>> variableAccessExpression)
{
var memberExpression = variableAccessExpression.Body as MemberExpression;
return memberExpression.Member.Name;
}
Run Code Online (Sandbox Code Playgroud)
...返回通过lambda表达式捕获的变量的名称:
static void Main(string[] args)
{
Console.WriteLine(GetVariableName(() => args));
// Output: "args"
int num = 0;
Console.WriteLine(GetVariableName(() => num));
// Output: "num"
}
Run Code Online (Sandbox Code Playgroud)
但是,这只能起作用,因为C#编译器将在匿名函数中捕获的任何局部变量(和参数)提升为幕后编译器生成的类中的同名实例变量(每个Jon Skeet).如果不是这种情况,则转换为Bodyto MemberExpression会失败,因为MemberExpression代表字段或属性访问.
这个变量是促销记录的行为,还是一个实现细节可能会在框架的其他版本中发生变化?
注意:这个问题是我前一个关于参数验证的概括.