我是c#和lambda表达式的新手;在this教程中,我无法理解代码对此Lambda表达式的作用:
public ViewModel()
{
base.AddRule(() => Aid, () =>
Aid.Length >= (5 * 2) &&
Aid.Length <= (16 * 2) &&
Aid.Length % 2 == 0, "Invalid AID.");
}
这是AddRule
方法,教程说它将规则添加到规则字典中:
public void AddRule<T>(Expression<Func<T>> expression, Func<bool> ruleDelegate, string errorMessage)
{
var name = GetPropertyName(expression);
ruleMap.Add(name, new Binder(ruleDelegate, errorMessage));
}
和
protected static string GetPropertyName<T>(Expression<Func<T>> expression)
{
if (expression == null)
throw new ArgumentNullException("expression");
Expression body = expression.Body;
MemberExpression memberExpression = body as MemberExpression;
if (memberExpression == null)
{
memberExpression = (MemberExpression)((UnaryExpression)body).Operand;
}
return memberExpression.Member.Name;
}
}
() => Aid
是什么意思以及为什么addrule
收到它并将其转换为UnaryExpression和MemberExpression?
答案 0 :(得分:2)
() => Aid
是() => { return Aid; }
的简写,它返回一个属性(或字段 - 您没有显示其声明)。通常这会导致匿名函数。
但是因为AddRule
方法采用Expression<Func<T>>
而不是Func<T>
,编译器会创建指令来创建AST(抽象语法树)而不是匿名函数。 AST可以编译成方法,但这里它只用于提取属性/字段的名称。
另一种方法是将属性名称作为字符串传递。使用成员表达式的优点在于它的重构友好:重命名属性也将更新此代码,确保规则仍与正确的属性相关联。
这是实际传递给AddRule
的内容(您可以手动执行此操作,但是您将失去对重构友好的好处 - 此外,() => Aid
更简洁):
Expression.Lambda<Func<T>>(
Expression.Property(
Expression.Constant(this),
"Aid"));
答案 1 :(得分:2)
MemberExpression是实例上的表达式或MemberInfo的静态表达式。
UnaryExpression是一个围绕目标和单个运算符的表达式(请参阅术语一元的定义)。这种运算符的一个很好的例子是演员。另一个是对值类型进行装箱或取消装箱的操作。
那么为什么获取MemberInfo的示例需要处理UnaryExpression?
考虑
public class Foo
{
public String RefType { get; set; }
public int ValueType { get; set; }
}
和一些代码
Expression<Func<Foo, object>> getter;
getter = f => f.RefType // compiler emits MemberExpression for RefType on a Foo instance
getter = f => f.ValueType // compiler emits an UnaryExpression to Box a MemberExpression for ValueType on a Foo instance.
答案 2 :(得分:1)
Aid
是该示例中使用的viewmodel的属性:
public string Aid
{
get { return Get(() => Aid); }
set { Set(() => Aid, value); }
}
如果您从该文章下载整个项目(链接在顶部)
,您可以检查这一点将属性传递给lambda表达式时,它将由MemberExpression表示。如MemberExpression Class
中所述,此课程专门用于此课程