C#

C# Fundamentals

19 lessons

Progress0%
1. Introduction to C#
1What is C#?
2. Variables and Data Types
1Data Types in C#
3. Control Flow
ConditionalsLoops
4. Methods
Defining MethodsOptional Parameters and Overloading
5. Object-Oriented Programming
Classes and PropertiesInheritanceInterfaces and Generics
6. LINQ and Async
LINQ Queriesasync/await
7. Exception Handling
try/catch/finally & Exception TypesCustom Exceptions & IDisposable
8. Delegates & Events
Delegates & LambdaEvents & Event Handlers
9. Records & Pattern Matching
Record TypesPattern Matching & Switch Expressions
10. File I/O & JSON
File & Stream OperationsJSON Serialization
All Tutorials
C#LINQ and Async
Lesson 10 of 19 min
Chapter 6 · Lesson 1

LINQ Queries

LINQ (Language Integrated Query) in C#

LINQ provides a unified, type-safe query syntax for collections, databases, XML, and more.

Common LINQ extension methods All operate on IEnumerable<T> and are lazy (evaluated on demand):

  • Where(predicate) — filters elements.
  • Select(selector) — projects/transforms elements.
  • OrderBy(keySelector) / OrderByDescending — sorts.
  • GroupBy(keySelector) — groups into key-collection pairs.
  • First(predicate) / FirstOrDefault — retrieves first match.
  • Count(predicate) — counts matching elements.
  • Any(predicate) — returns true if any element matches.
  • All(predicate) — returns true if all elements match.

Method vs query syntax

csharp
// Method syntax
var result = data.Where(x => x.Age > 18).Select(x => x.Name);
// Query syntax
var result = from x in data where x.Age > 18 select x.Name;

Key points:

  • LINQ queries are lazy — they execute when iterated (foreach, ToList, etc.).
  • ToList() and ToArray() force immediate evaluation.
  • Lambda expressions are the heart of method-syntax LINQ.

Code Examples

Where, Select, OrderBycsharp
using System;
using System.Collections.Generic;
using System.Linq;

class Program {
    record Product(string Name, string Category, decimal Price);

    static void Main() {
        var products = new List<Product> {
            new("Apple", "Fruit", 0.5m),
            new("Laptop", "Tech", 999m),
            new("Banana", "Fruit", 0.3m),
            new("Phone", "Tech", 599m),
            new("Cherry", "Fruit", 2m),
        };

        var cheapFruits = products
            .Where(p => p.Category == "Fruit" && p.Price < 1)
            .OrderBy(p => p.Price)
            .Select(p => $"{p.Name}: ${p.Price}");

        foreach (var item in cheapFruits)
            Console.WriteLine(item);

        Console.WriteLine($"Any tech over $800: {products.Any(p => p.Category == "Tech" && p.Price > 800)}");
        Console.WriteLine($"All fruits under $5: {products.Where(p => p.Category == "Fruit").All(p => p.Price < 5)}");
    }
}

LINQ chains are read top-to-bottom: filter, sort, then project. Lazy evaluation means the chain only runs when iterated.

GroupBy and aggregatescsharp
using System;
using System.Collections.Generic;
using System.Linq;

class Program {
    record Sale(string Region, decimal Amount);

    static void Main() {
        var sales = new List<Sale> {
            new("North", 100), new("South", 200),
            new("North", 150), new("East", 300),
            new("South", 250), new("East", 100),
        };

        var byRegion = sales
            .GroupBy(s => s.Region)
            .Select(g => new { Region = g.Key, Total = g.Sum(s => s.Amount), Count = g.Count() })
            .OrderByDescending(r => r.Total);

        foreach (var r in byRegion)
            Console.WriteLine($"{r.Region}: ${r.Total} ({r.Count} sales)");
    }
}

GroupBy partitions elements into groups by key. Projecting each group with Select lets you compute per-group aggregates.

Quick Quiz

1. When does a LINQ query actually execute?

2. What does `Any(predicate)` return if no elements match?

Was this lesson helpful?

PreviousNext