我可以在LINQ投影中捕获异常吗?

时间:2011-04-17 16:11:49

标签: c# linq exception

假设我写了一个关于我的C盘上隐藏文件的信息的linq查询:

var q2 =
    from c in Directory.EnumerateFiles("C:\\")
    where Regex.IsMatch(c, @"^C:\\\.")
    select c;

var q3 =
    from c in q2
    let info = new 
    {
        File = c,
        FileSecurity = File.GetAccessControl(c),
        FileAttributes = File.GetAttributes(c),
        CreatedUTC = File.GetCreationTimeUtc(c),
        AccessedUTC = File.GetLastAccessTimeUtc(c),
        ModifiedUTC = File.GetLastWriteTimeUtc(c)
    }
    select info;

以上是一个逻辑示例,可能希望在捕获异常时继续运行,但我不知道如何在这种C#编程风格中实现(或者如果可能的话)。

从概念上讲,我想要一些“continue”语句,可以放在LINQ查询周围的catch块的主体中​​。

try
{
   // LINQ QUERY
}
catch(Exception ex)
{
  Logger.Log("error...");
  continue;
}

1 个答案:

答案 0 :(得分:2)

由于LINQ的惰性,当您开始使用迭代器而不是构建查询时,可能需要try/catch

var q3 = ...

try
{
    foreach (var item in q3)
    {
        ...
    }
} 
catch(Exception ex)
{

}

Directory.EnumerateFiles只返回一个IEnumerable<string>,在您开始迭代之前不会进行任何评估。


更新:

如果抛出异常,为了避免中断循环,您可以执行以下操作:

static void Main()
{
    var q = Enumerable.Range(1, 5).Select(x =>
    {
        if (x % 2 == 0)
        {
            throw new Exception();
        }
        return x;
    });

    using (var enumerator = q.GetEnumerator())
    {
        while (true)
        {
            try
            {
                bool hasNext = enumerator.MoveNext();
                if (!hasNext)
                {
                    break;
                }

                Console.WriteLine(enumerator.Current);
            }
            catch (Exception ex)
            {
                // TODO: do something with the exception here
            }
        }
    }
}