更新 :这不再是从C#6,它推出了一个问题
nameof
运营商来解决这样的场景(参见MSDN )。注 :请参阅“ 通过lambda表达式在运行时局部变量(和参数)的入门名 ”对这个问题的概括,以及一些答案。
我喜欢用lambda表达式创建的重构安全实现的想法INotifyPropertyChanged
接口,使用类似于提供代码埃里克·德Carufel 。
我与实施提供参数名称的类似实验ArgumentException
在重构安全的方式(或其派生类)。
我已经定义用于执行以下方法效用null
检查:
public static void CheckNotNull<T>(Expression<Func<T>> parameterAccessExpression)
{
Func<T> parameterAccess = parameterAccessExpression.Compile();
T parameterValue = parameterAccess();
CheckNotNull(parameterValue, parameterAccessExpression);
}
public static void CheckNotNull<T>(T parameterValue,
Expression<Func<T>> parameterAccessExpression)
{
if (parameterValue == null)
{
Expression bodyExpression = parameterAccessExpression.Body;
MemberExpression memberExpression = bodyExpression as MemberExpression;
string parameterName = memberExpression.Member.Name;
throw new ArgumentNullException(parameterName);
}
}
参数验证然后可以使用以下语法一个重构安全的方式来执行:
CheckNotNull(() => arg); // most concise
CheckNotNull(arg, () => args); // equivalent, but more efficient
我关心的是下面几行:
Expression bodyExpression = parameterAccessExpression.Body;
MemberExpression memberExpression = bodyExpression as MemberExpression;
甲MemberExpression
代表“访问字段或属性”。 这是保证在正常工作INotifyPropertyChanged
情况下,由于lambda表达式将是一个属性访问。
然而,在上述我的代码,lambda表达式是语义上的参数访问,而不是一个字段或属性的访问。 代码工作的唯一原因是,C#编译器促进了在匿名函数幕后编译器生成的类中捕捉到的实例变量的任何局部变量(和参数)。 这是通过证实乔恩斯基特 。
我的问题是:这种行为是在.NET规范中记录(促进捕获参数,以实例变量),或者是它只是实现的细节可以在可选的实施方式或框架的未来版本的变化? 具体而言,可能会有环境下parameterAccessExpression.Body is MemberExpression
返回false
?