我正在尝试编写一些逻辑来确定集合中某个对象的某个属性的所有值是否为数字且大于零。我可以使用ForEach轻松编写此内容,但我想使用Linq to Object执行此操作。我试过这个:
var result = entity.Reports.Any(
x =>
x.QuestionBlock == _question.QuestionBlock
&& (!string.IsNullOrEmpty(x.Data)) && Int32.TryParse(x.Data, out tempVal)
&& Int32.Parse(x.Data) > 0);
它无法正常工作。我也试过这个,希望Int32上的TryParse()在第一次遇到无法解析为int的字符串时返回false。但是看起来out参数将包含可以解析为int的第一个值字符串值。
var result = entity.GranteeReportDataModels.Any(
x =>
x.QuestionBlock == _question.QuestionBlock
&& (!string.IsNullOrEmpty(x.Data)) && Int32.TryParse(x.Data, out tempVal));
非常感谢任何帮助!
答案 0 :(得分:3)
如果您想测试“所有”值是否符合条件,则应使用All
IEnumerable<T>
扩展方法,而不是Any
。我会这样写:
var result = entity.Reports.All(x =>
{
int result = 0;
return int.TryParse(x.Data, out result) && result > 0;
});
我认为您不需要测试null或空字符串,因为如果传入null或空字符串,int.TryPrase
将返回false。
答案 1 :(得分:1)
var allDataIsNatural = entity.Reports.All(r =>
{
int i;
if (!int.TryParse(r.Data, out i))
{
return false;
}
return i > 0;
});
Any
会在第一行为true
时返回,但您明确表示要检查所有。
答案 2 :(得分:0)
您可以使用此扩展程序尝试将字符串解析为int
并返回int?
:
public static int? TryGetInt(this string item)
{
int i;
bool success = int.TryParse(item, out i);
return success ? (int?)i : (int?)null;
}
然后此查询有效:
bool all = entity.Reports.All(x => {
if(x.QuestionBlock != _question.QuestionBlockint)
return false;
int? data = x.Data.TryGetInt();
return data.HasValue && data.Value > 0;
});
或更具可读性(效率稍低):
bool all = entityReports
.All(x => x.Data.TryGetInt().HasValue && x.Data.TryGetInt() > 0
&& x.QuestionBlock == _question.QuestionBlockint);
此方法避免将局部变量用作out
参数,这是Linq-To-Objects中的未记录行为,并且可能在将来停止工作。它也更具可读性。