Cómo: Controlar excepciones con expresiones de consultas (Guía de programación de C#)

Es posible llamar a cualquier método en el contexto de una expresión de consulta.Sin embargo, se recomienda que evite llamar a cualquier método en una expresión de consulta que pueda crear un efecto secundario, como modificar el contenido del origen de datos o producir una excepción.En este ejemplo se muestra cómo evitar que se produzcan excepciones al llamar a métodos en una expresión de consulta sin infringir las directrices generales de .NET Framework sobre el control de excepciones.Dichas directrices indican que es aceptable detectar una excepción específica cuando se entiende por qué se producirá en un contexto determinado.Para obtener más información, vea Procedimientos recomendados para controlar excepciones.

En el último ejemplo se muestra cómo controlar los casos en los que se debe producir una excepción durante la ejecución de una consulta.

Ejemplo

En el ejemplo siguiente se muestra cómo mover código de control de excepciones fuera de una expresión de consulta.Esto sólo es posible cuando el método no depende de variables locales de la consulta.

class ExceptionsOutsideQuery
{
    static void Main()
    {
        // DO THIS with a datasource that might
        // throw an exception. It is easier to deal with
        // outside of the query expression.
        IEnumerable<int> dataSource;
        try
        {
            dataSource = GetData();
        }
        catch (InvalidOperationException)
        {
            // Handle (or don't handle) the exception 
            // in the way that is appropriate for your application.
            Console.WriteLine("Invalid operation");
            goto Exit;
        }

        // If we get here, it is safe to proceed.
        var query = from i in dataSource
                    select i * i;

        foreach (var i in query)
            Console.WriteLine(i.ToString());

        //Keep the console window open in debug mode
        Exit:
        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }

    // A data source that is very likely to throw an exception!
    static IEnumerable<int> GetData()
    {
        throw new InvalidOperationException();
    }
}

En algunos casos, la mejor respuesta a una excepción que se produce desde una consulta puede ser detener la ejecución de la consulta inmediatamente.En el ejemplo siguiente se muestra cómo controlar excepciones que pueden producirse desde el cuerpo de una consulta.Suponga que SomeMethodThatMightThrow puede producir una excepción que requiere que se detenga la ejecución de la consulta.

Observe que el bloque try incluye el bucle foreach y no la consulta en sí.Esto se debe a que el bucle foreach es el punto en el que se ejecuta la consulta realmente.Para obtener más información, vea Introducción a las consultas LINQ (C#).

class QueryThatThrows
{
    static void Main()
    {
        // Data source.
        string[] files = { "fileA.txt", "fileB.txt", "fileC.txt" };

        // Demonstration query that throws.
        var exceptionDemoQuery =
            from file in files
            let n = SomeMethodThatMightThrow(file)
            select n;

        // Runtime exceptions are thrown when query is executed.
        // Therefore they must be handled in the foreach loop.
        try
        {
            foreach (var item in exceptionDemoQuery)
            {
                Console.WriteLine("Processing {0}", item);
            }
        }

        // Catch whatever exception you expect to raise
        // and/or do any necessary cleanup in a finally block
        catch (InvalidOperationException e)
        {
            Console.WriteLine(e.Message);
        }

        //Keep the console window open in debug mode
        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }

    // Not very useful as a general purpose method.
    static string SomeMethodThatMightThrow(string s)
    {
        if (s[4] == 'C')
            throw new InvalidOperationException();
        return @"C:\newFolder\" + s;
    }
}
/* Output:
    Processing C:\newFolder\fileA.txt
    Processing C:\newFolder\fileB.txt
    Operation is not valid due to the current state of the object.
 */

Compilar el código

  • Cree un proyecto de Visual Studio para la versión 3.5 de .NET Framework.De manera predeterminada, el proyecto incluye una referencia a System.Core.dll y una directiva using para el espacio de nombres System.Linq.

  • Copie el código en el proyecto.

  • Presione F5 para compilar y ejecutar el programa.

Presione cualquier tecla para salir de la ventana de consola.

Vea también

Conceptos

Expresiones de consultas LINQ (Guía de programación de C#)