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

发布于 2024-11-02 05:25:54 字数 765 浏览 0 评论 0原文

假设我编写了一个 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# 编程风格(或者如果可能的话)。

从概念上讲,我想要某种“继续”语句,可以将其放入围绕 LINQ 查询的 catch 块的主体中​​。

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

Say I write a linq query for info about the hidden files on my C drive:

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;

The above is an example of logic that might want to keep going when an exception is caught, but I don't know how to get that to happen in this style of C# programming (or if its possible).

Conceptually I want some kind of "continue" statement that can be put in the body of a catch block surrounding a LINQ query.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

独木成林 2024-11-09 05:25:54

由于 LINQ 的惰性本质,您可能需要在开始使用迭代器时而不是在构建查询时进行尝试/捕获:

var q3 = ...

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

}

Directory.EnumerateFiles 仅返回一个 IEnumerable 并且在开始之前不会进行任何评估迭代它。


更新:

为了避免在抛出异常时跳出循环,您可以执行以下操作:

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

Due to the lazy nature of LINQ you might need to try/catch when you start consuming the iterator and not when building the query:

var q3 = ...

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

}

The Directory.EnumerateFiles simply returns an IEnumerable<string> and no evaluation happens until you start iterating over it.


UPDATE:

To avoid breaking out of the loop if an exception is thrown you could do the following:

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
            }
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文