c# – 使用表达式从Lambda创建安全的深层属性访问器
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 使用表达式从Lambda创建安全的深层属性访问器,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2241字,纯文字阅读大概需要4分钟。
内容图文
![c# – 使用表达式从Lambda创建安全的深层属性访问器](/upload/InfoBanner/zyjiaocheng/785/845ed069828a494fa175624d85053201.jpg)
我的目标是使用Lambdas创建一个属性绑定对象,可以安全地检索深属性值.通过安全,如果以前的属性之一为null而不是抛出空引用异常,则返回属性类型的默认值.
方法签名:
public static Func<TO, TP> BuildSafeAccessor<TO, TP>(this Expression<Func<TO, TP>> propertyExpression) where TO: class
{
}
*编辑:澄清我的问题
所以,如果我打电话:
var safeAccessor = BuildSafeAccessor<Person>(p => p.Address.Zip);
当调用safeAccessor时,它的逻辑如下:
if (p.Address == null)
return default(TP);
return p.Address.Zip;
解决方法:
这里的关键观察是你不需要“已经完全创建的ifFalse表达式”,你可以递归地构建它.
代码可能如下所示:
public static Func<TO, TP> BuildSafeAccessor<TO, TP>(Expression<Func<TO, TP>> propertyExpression)
{
var properties = GetProperties(propertyExpression.Body);
var parameter = propertyExpression.Parameters.Single();
var nullExpression = Expression.Constant(default(TP), typeof(TP));
var lambdaBody = BuildSafeAccessorExpression(parameter, properties, nullExpression);
var lambda = Expression.Lambda<Func<TO, TP>>(lambdaBody, parameter);
return lambda.Compile();
}
private static Expression BuildSafeAccessorExpression(Expression init, IEnumerable<PropertyInfo> properties, Expression nullExpression)
{
if (!properties.Any())
return init;
var propertyAccess = Expression.Property(init, properties.First());
var nextStep = BuildSafeAccessorExpression(propertyAccess, properties.Skip(1), nullExpression);
return Expression.Condition(
Expression.ReferenceEqual(init, Expression.Constant(null)), nullExpression, nextStep);
}
private static IEnumerable<PropertyInfo> GetProperties(Expression expression)
{
var results = new List<PropertyInfo>();
while (expression is MemberExpression)
{
var memberExpression = (MemberExpression)expression;
results.Add((PropertyInfo)memberExpression.Member);
expression = memberExpression.Expression;
}
if (!(expression is ParameterExpression))
throw new ArgumentException();
results.Reverse();
return results;
}
(请注意,此代码使用LINQ效率低下,以使其更具可读性.)
如果你在lambda a =>上运行它a.B.C.D,它将创建一个表达式(在其上显示ToString()的结果):
a => IIF((a == null), null, IIF((a.B == null), null, IIF((a.B.C == null), null, a.B.C.D)))
请注意,这最多可以访问a.B三次.如果该属性很慢或有副作用,那可能是个问题.如果这对您来说是个问题,我认为您需要使用带局部变量的Blocks.
内容总结
以上是互联网集市为您收集整理的c# – 使用表达式从Lambda创建安全的深层属性访问器全部内容,希望文章能够帮你解决c# – 使用表达式从Lambda创建安全的深层属性访问器所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。