对对象的LINQ查询有疑问......
我有这个过滤器描述,我希望保密,并且在代码中的给定检查点,我设置了一些活动的标志。在处理结束时,我想过滤活动标志。
如果有任何标志处于活动状态,我想将它们写入控制台。 (我希望所有标记的检查点都在一个字符串中,所以我可以更改代码以便稍后抛出异常)。
这是代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
namespace checkpoints
{
public class Program
{
public static void Main(string[] args)
{
var filters = new Filters().FilterList;
filters[0].flag = true;
filters[2].flag = true;
var query = filters.Where(f => f.flag).Select(f => f.desc);
Console.WriteLine("Filter points active: ");
string fpoints = System.String.Empty;
foreach(string fp in query)
{ fpoints = fpoints + fp + System.Environment.NewLine; }
Console.WriteLine(fpoints);
}
}
public class Filters
{
public List<Filter> FilterList = new List<Filter>{};
public Filters()
{
foreach(var def in Filters.def_desc)
{ this.FilterList.Add(new Filter(false, def)); }
}
private readonly static string[] def_desc = new string[3]
{ "Filter AX2123: Failed file write.",
"Filter XVB231: Failed table load.",
"Filter FZD358: Transaction halted." };
public class Filter
{
public bool flag;
public readonly string desc;
public Filter(bool flag, string desc)
{
this.flag = flag;
this.desc = desc;
}
}
}
}
有效。我的问题是需要为LINQ查询结果(我猜是IEnumerable<Filter>
)运行一个for,以便提取字符串。如果我已经运行了一个查询(即遍布代码)为什么我需要“再次运行”?看起来它很可怕并且不是很优雅......有什么想法吗?
答案 0 :(得分:2)
var query = filters.Where(f => f.flag).Select(f => f.desc);
的调用不会运行查询。调用链返回的IEnumerable<Filter>
不会收集Filter
个对象,直到您在foreach
循环中枚举返回结果为止。
这有利有弊。优点是,在不需要查询结果的情况下,可以节省评估查询所需的所有CPU时间。缺点是如果需要多次枚举结果,系统第二次需要再次重新计算结果。解决上一个问题的方法是立即枚举您的查询结果,并将它们放入数组或列表中,如下所示:
var queryResults = filters.Where(f => f.flag).Select(f => f.desc).ToList();
答案 1 :(得分:2)
由于dasblinkenlight和Daev已经提到了延迟执行部分,我认为你有兴趣知道你可以通过替换
来加入字符串而不用foreachforeach(string fp in query)
{ fpoints = fpoints + fp + System.Environment.NewLine; }
与
string.Join(Environment.NewLine, query)
答案 2 :(得分:2)
string fpoint=query.Aggregate((c, c1) => c + System.Environment.NewLine+ c1 );
答案 3 :(得分:1)
您的query
变量是表达式,在枚举之前(在您的情况下由foreach
进行枚举)不会进行评估。如果您使用调试器检查query
,则不会将其内容视为Filter
的集合而是查询以获取结果。这被称为“延迟执行”,在Blog Post中很好地涵盖了(虽然它的Linq-SQL适用相同的主体)。
答案 4 :(得分:1)
如果你想摆脱你的foreach,那么你可以尝试一些傻瓜。
string.Join(Environment.NewLine, query.ToArray());
如果我没有仔细阅读你的问题,请道歉:)
答案 5 :(得分:0)
你所追求的是名为aggregate的LINQ函数。它会将列表项连在一起组成一个输出。
快速谷歌显示此stackoverflow帖子显示如何使用聚合函数:Linq Aggregate function
一个简单的例子就是在这里使用函数:http://blueonionsoftware.com/blog.aspx?p=509fa3f8-c125-4e61-9227-8ca4c4e29210。这个例子使用逗号,你可以改用新行。