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

本文关键字:捕获异常 投影 LINQ 我可以 | 更新日期: 2023-09-27 17:50:19

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

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;
}

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

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

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

目录。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
            }
        }
    }
}