Expression<Func<T>>
并检查每个为null,然后再转到该系列中的下一个对象。
没有try / catch 我需要检查给定的调用是否会产生错误:
A)索引超出范围(集合有10个成员,表达式如下):
var answer = NullPropagation(() => item.Location.PhoneNumbers[500]);
B)集合为空(集合没有成员,表达式如下):
var answer = NullPropagation(() => item.Location.PhoneNumbers.First());
var members = new List<Expression>();
......填写收藏品等
var previousMethod = (MethodInfo) null;
var nullFound = members.Any(x =>
{
if (previousMethod != null && typeof(IEnumerable).IsAssignableFrom(previousMethod.ReturnType))
{
Console.WriteLine("HIT!");
//Todo: Detect collection empty/index out of range, return true;
}
previousMethod = method;
return Expression.Lambda(x).Compile().DynamicInvoke() == null;
}
...
答案 0 :(得分:0)
经过广泛研究后,我修复了索引访问问题,但是我选择不纠正linq问题,这就是原因:
首先,可以检查该方法是否是由于空集合而导致错误的以下任何linq查询,然后在集合上检查!.Any():
这里的问题是可以为这些中的任何一个提供谓词,这将限制集合,以便仍然返回错误。处理该场景的选项有限。我们需要使用try / catch来处理它(我想要避免的事情)或者在IEnumerable Linq扩展中重新创建内部逻辑,报告找到null而不是抛出错误。这两种解决方案都是黑客,对我来说不值得。如果您正在阅读本文并对此方法非常感兴趣,我可以提供我作为概念证明放在一起的代码。
话虽如此,我确实纠正了索引访问问题,这里是解决方案,在if块里面的HIT!控制台写信是我的问题:
var collectionAccessMethod = method.Body as MethodCallExpression;
if (collectionAccessMethod != null &&
previousMethod.ReturnType.GetProperties()
.Where(p => p.GetIndexParameters().Any())
.Select(p => p.GetGetMethod())
.Contains(collectionAccessMethod.Method))
{
var index = (int) Expression.Lambda(collectionAccessMethod.Arguments[0]).Compile().DynamicInvoke();
var collection = ((Func<IEnumerable>)Expression.Lambda(previousMethod).Compile().DynamicInvoke()).Invoke();
if (index > collection.Cast<object>().Count() - 1)
{
return true;
}
}