Compartir a través de


Características de C# que admiten LINQ

Expresiones de consulta

Las expresiones de consulta usan una sintaxis declarativa similar a SQL o XQuery para consultar sobre System.Collections.Generic.IEnumerable<T> colecciones. En tiempo de compilación, la sintaxis de consulta se convierte en llamadas de método a la implementación de un proveedor LINQ de los métodos de consulta estándar. Las aplicaciones controlan los operadores de consulta estándar que están dentro del alcance especificando el espacio de nombres adecuado con la directiva using. La siguiente expresión de consulta toma una matriz de cadenas, las agrupa según el primer carácter de la cadena y ordena los grupos.

var query = from str in stringArray
            group str by str[0] into stringGroup
            orderby stringGroup.Key
            select stringGroup;

Variables con tipo implícito (var)

Puede usar el modificador var para indicar al compilador que infiera y asigne el tipo, como se muestra aquí:

var number = 5;
var name = "Virginia";
var query = from str in stringArray
            where str[0] == 'm'
            select str;

Las variables declaradas como var están fuertemente tipadas, como las variables cuyo tipo se especifica explícitamente. El uso de var permite crear tipos anónimos, pero solo para variables locales. Para obtener más información, vea Variables locales con tipo implícito.

Inicializadores de objeto y colección

Los inicializadores de objeto y colección permiten inicializar objetos sin llamar explícitamente a un constructor para el objeto. Los inicializadores se suelen usar en expresiones de consulta cuando proyectan los datos de origen en un nuevo tipo de datos. Suponiendo una clase denominada Customer con propiedades públicas Name y Phone, el inicializador de objeto se puede usar como en el siguiente código.

var cust = new Customer { Name = "Mike", Phone = "555-1212" };

Continuando con su clase Customer, supongamos que hay un origen de datos denominado IncomingOrders y que, para cada pedido con un gran OrderSize, desea crear un nuevo Customer basado en ese pedido. Una consulta LINQ se puede ejecutar en este origen de datos y usar la inicialización de objetos para rellenar una colección:

var newLargeOrderCustomers = from o in IncomingOrders
                            where o.OrderSize > 5
                            select new Customer { Name = o.Name, Phone = o.Phone };

Es posible que el origen de datos tenga más propiedades definidas que la Customer clase como OrderSize, pero con la inicialización de objetos, los datos devueltos de la consulta se moldean en el tipo de datos deseado; se eligen los datos pertinentes para la clase. Como resultado, ahora tienes un System.Collections.Generic.IEnumerable<T> lleno de los nuevos elementos Customer que querías. El ejemplo anterior también se puede escribir en la sintaxis del método de LINQ:

var newLargeOrderCustomers = IncomingOrders.Where(x => x.OrderSize > 5).Select(y => new Customer { Name = y.Name, Phone = y.Phone });

A partir de C# 12, puede usar una expresión de colección para inicializar una colección.

Para obtener más información, consulte:

Tipos anónimos

El compilador crea un tipo anónimo. El nombre del tipo solo está disponible para el compilador. Los tipos anónimos proporcionan una manera cómoda de agrupar temporalmente un conjunto de propiedades en un resultado de consulta sin tener que definir un tipo con nombre independiente. Los tipos anónimos se inicializan con una nueva expresión y un inicializador de objeto, como se muestra aquí:

select new {name = cust.Name, phone = cust.Phone};

A partir de C# 7, puede usar tuplas para crear tipos sin nombre.

Métodos de extensión.

Un método de extensión es un método estático que se puede asociar a un tipo, de modo que se pueda llamar como si fuera un método de instancia en el tipo. Esta característica le permite, en efecto, agregar nuevos métodos a los tipos existentes sin modificarlos realmente. Los operadores de consulta estándar son un conjunto de métodos de extensión que proporcionan funcionalidad de consulta LINQ para cualquier tipo que implemente IEnumerable<T>.

Expresiones lambda

Una expresión lambda es una función en línea que usa el => operador para separar los parámetros de entrada del cuerpo de la función y que en tiempo de compilación se puede convertir en un delegado o en un árbol de expresión. En la programación LINQ, se producen expresiones lambda al realizar llamadas de método directo a los operadores de consulta estándar.

Expresiones como datos

Los objetos de consulta se pueden componer, lo que significa que puede devolver una consulta desde un método . Los objetos que representan consultas no almacenan la colección resultante, sino los pasos para generar los resultados cuando sea necesario. La ventaja de devolver objetos de consulta desde métodos es que se pueden componer o modificar todavía más. Por lo tanto, cualquier valor devuelto o out parámetro de un método que devuelva una consulta también debe tener ese tipo. Si un método materializa una consulta en un tipo List<T> o Array concreto, devuelve los resultados de la consulta en lugar de la propia consulta. Una variable de consulta que se devuelve de un método todavía se puede componer o modificar.

En el ejemplo siguiente, el primer método QueryMethod1 devuelve una consulta como un valor devuelto y el segundo método QueryMethod2 devuelve una consulta como parámetro out (returnQ en el ejemplo). En ambos casos, es una consulta que se devuelve, no los resultados de la consulta.

IEnumerable<string> QueryMethod1(int[] ints) =>
    from i in ints
    where i > 4
    select i.ToString();

void QueryMethod2(int[] ints, out IEnumerable<string> returnQ) =>
    returnQ = from i in ints
              where i < 4
              select i.ToString();

int[] nums = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ];

var myQuery1 = QueryMethod1(nums);

La consulta myQuery1 se ejecuta en el siguiente bucle foreach.

foreach (var s in myQuery1)
{
    Console.WriteLine(s);
}

Reste el puntero del mouse sobre myQuery1 para ver su tipo.

También puede ejecutar la consulta devuelta desde QueryMethod1 directamente, sin usar myQuery1.

foreach (var s in QueryMethod1(nums))
{
    Console.WriteLine(s);
}

Reste el puntero del mouse sobre la llamada a QueryMethod1 para ver su tipo de valor devuelto.

QueryMethod2 devuelve una consulta como el valor de su out parámetro:

QueryMethod2(nums, out IEnumerable<string> myQuery2);

// Execute the returned query.
foreach (var s in myQuery2)
{
    Console.WriteLine(s);
}

Puede modificar una consulta mediante la composición de la consulta. En este caso, el objeto de consulta anterior se usa para crear un nuevo objeto de consulta. Este nuevo objeto devuelve resultados diferentes a los del objeto de consulta original.

myQuery1 = from item in myQuery1
           orderby item descending
           select item;

// Execute the modified query.
Console.WriteLine("\nResults of executing modified myQuery1:");
foreach (var s in myQuery1)
{
    Console.WriteLine(s);
}