Могу ли я перехватить исключение в проекции LINQ? - PullRequest
1 голос
/ 17 апреля 2011

Скажем, я пишу запрос 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", который можно поместить в тело блока catch, окружающего запрос LINQ.

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

1 Ответ

2 голосов
/ 17 апреля 2011

Из-за ленивого характера 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
            }
        }
    }
}
...