.NET Documentation

Explore the power of the .NET ecosystem.

LINQ to Objects

LINQ to Objects enables you to use Language Integrated Query (LINQ) with any .NET collection that implements the IEnumerable<T> interface, such as arrays, lists, and dictionaries. This powerful feature allows you to query data directly in memory without the need for an external data source like a database or XML file.

Core Concepts

LINQ to Objects leverages standard LINQ query operators and a fluent syntax (method syntax) or query syntax to express queries against in-memory collections. The key components are:

Query Syntax vs. Method Syntax

LINQ provides two syntaxes for writing queries:

Query Syntax

This syntax is similar to SQL and is often more readable for simple queries.


var numbers = new[] { 1, 5, 3, 9, 2, 7, 4, 8, 6 };

var evenNumbers = from num in numbers
                  where num % 2 == 0
                  orderby num
                  select num;

foreach (var n in evenNumbers)
{
    Console.WriteLine(n);
}
        

Method Syntax

This syntax uses extension methods and is generally more flexible and powerful for complex queries or when combining LINQ with other .NET features.


var numbers = new[] { 1, 5, 3, 9, 2, 7, 4, 8, 6 };

var evenNumbers = numbers.Where(num => num % 2 == 0)
                         .OrderBy(num => num);

foreach (var n in evenNumbers)
{
    Console.WriteLine(n);
}
        

Common Query Operators

Here are some of the most frequently used LINQ query operators:

Example: Querying a List of Objects

Let's say you have a list of Product objects and want to find all products with a price greater than $50, ordered by name.


public class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}

// ... inside a method ...

var products = new List<Product>
{
    new Product { Name = "Laptop", Price = 1200.00M },
    new Product { Name = "Mouse", Price = 25.00M },
    new Product { Name = "Keyboard", Price = 75.00M },
    new Product { Name = "Monitor", Price = 300.00M },
    new Product { Name = "Webcam", Price = 45.00M }
};

var expensiveProducts = from p in products
                        where p.Price > 50.00M
                        orderby p.Name
                        select p;

Console.WriteLine("Expensive Products:");
foreach (var prod in expensiveProducts)
{
    Console.WriteLine($"- {prod.Name} (${prod.Price:N2})");
}
            

Deferred Execution

A key characteristic of LINQ is deferred execution. This means that the actual query execution is postponed until you iterate over the query results. This is efficient because the query logic is only performed when the data is absolutely needed.

Consider this:


var numbers = new List<int> { 1, 2, 3, 4, 5 };
var query = numbers.Select(n => { Console.WriteLine($"Processing {n}"); return n * 2; });

// Nothing is printed yet!
Console.WriteLine("Query defined, but not executed.");

// Execution happens here when iterating
foreach (var item in query)
{
    Console.WriteLine($"Result: {item}");
}
        

This behavior allows you to modify the underlying data source between query definition and execution, although this can lead to unexpected results if not managed carefully.

Benefits of LINQ to Objects

LINQ to Objects is a fundamental part of working with data in C# and .NET, making in-memory data manipulation more intuitive and efficient.