DEV Community

Cover image for Common LINQ Methods with Examples in .NET Core
Sapana Pal
Sapana Pal

Posted on

Common LINQ Methods with Examples in .NET Core

Here's a comprehensive list of LINQ (Language Integrated Query) extension methods available in .NET Core. These methods are part of the System.Linq namespace and are used to query collections, databases, XML, and other data sources.

Common LINQ Extension Methods in .NET Core

Basic Query Operators

  • Where: Filters a sequence based on a predicate.
  • Select: Projects each element of a sequence into a new form.
  • SelectMany: Projects each element of a sequence to an IEnumerable and flattens the resulting sequences into one sequence.
  • OrderBy: Sorts elements in ascending order.
  • OrderByDescending: Sorts elements in descending order.
  • ThenBy: Performs a secondary sort in ascending order.
  • ThenByDescending: Performs a secondary sort in descending order.
  • Reverse: Reverses the order of the sequence.
  • Distinct: Returns distinct elements from a sequence.
  • Union: Produces the set union of two sequences.
  • Intersect: Produces the set intersection of two sequences.
  • Except: Produces the set difference of two sequences.

Quantifiers

  • Any: Checks if any elements satisfy a condition.
  • All: Checks if all elements satisfy a condition.
  • Contains: Checks if a sequence contains a specific element.

Aggregation

  • Count: Counts elements in a sequence.
  • Sum: Computes the sum of sequence elements.
  • Min: Finds the minimum element.
  • Max: Finds the maximum element.
  • Average: Computes the average of sequence elements.

Partitioning

  • Skip: Skips a specified number of elements.
  • SkipWhile: Skips elements while a condition is true.
  • Take: Takes a specified number of elements.
  • TakeWhile: Takes elements while a condition is true.

Element Operations

  • First: Returns the first element.
  • FirstOrDefault: Returns the first element or default if empty.
  • Last: Returns the last element.
  • LastOrDefault: Returns the last element or default if empty.
  • Single: Returns the only element, throws if there are zero or more than one.
  • SingleOrDefault: Returns the only element or default if empty.

Equality and Set Operations

  • SequenceEqual: Checks if two sequences are equal.

Conversion

  • ToList: Converts to List.
  • ToArray: Converts to array.
  • ToDictionary: Converts to Dictionary.
  • AsEnumerable: Treats the source as IEnumerable.

Grouping

  • GroupBy: Groups elements according to a key selector.

Joining

  • Join: Inner join.
  • GroupJoin: Group join (left outer join).

Lazy Evaluation

  • AsQueryable: Converts an IEnumerable to IQueryable for deferred execution.

Other

  • Aggregate: Performs a custom aggregation over a sequence.
  • DefaultIfEmpty: Provides a default value if sequence is empty.
  • ElementAt: Returns element at a specific index.
  • ElementAtOrDefault: Returns element at index or default.

Certainly! Here's a comprehensive example that demonstrates all the listed basic query operators in a single program. This example uses a list of objects representing people with properties like Name and Age.

using System;
using System.Collections.Generic;
using System.Linq;

namespace LinqExamples
{
    class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }

    class Program
    {
        static void Main()
        {
            // Sample data
            List<Person> people = new List<Person>
            {
                new Person { Name = "Alice", Age = 30 },
                new Person { Name = "Bob", Age = 25 },
                new Person { Name = "Charlie", Age = 35 },
                new Person { Name = "Alice", Age = 28 },
                new Person { Name = "Eve", Age = 40 },
                new Person { Name = "Frank", Age = 25 }
            };

            // 1. Where: Filter people older than 28
            var olderThan28 = people.Where(p => p.Age > 28);
            Console.WriteLine("People older than 28:");
            foreach (var person in olderThan28)
                Console.WriteLine($"{person.Name}, {person.Age}");

            Console.WriteLine();

            // 2. Select: Select names only
            var names = people.Select(p => p.Name);
            Console.WriteLine("Names of all people:");
            foreach (var name in names)
                Console.WriteLine(name);

            Console.WriteLine();

            // 3. SelectMany: Flatten list of characters in names
            var characters = people.SelectMany(p => p.Name.ToCharArray());
            Console.WriteLine("All characters in names:");
            foreach (var ch in characters)
                Console.Write($"{ch} ");
            Console.WriteLine("\n");

            // 4. OrderBy: Sort by Age ascending
            var sortedByAge = people.OrderBy(p => p.Age);
            Console.WriteLine("Sorted by age (ascending):");
            foreach (var person in sortedByAge)
                Console.WriteLine($"{person.Name}, {person.Age}");

            Console.WriteLine();

            // 5. OrderByDescending: Sort by Age descending
            var sortedByAgeDesc = people.OrderByDescending(p => p.Age);
            Console.WriteLine("Sorted by age (descending):");
            foreach (var person in sortedByAgeDesc)
                Console.WriteLine($"{person.Name}, {person.Age}");

            Console.WriteLine();

            // 6. ThenBy: Secondary sort by Name ascending
            var sortedByAgeThenName = people
                .OrderBy(p => p.Age)
                .ThenBy(p => p.Name);
            Console.WriteLine("Sorted by age, then by name:");
            foreach (var person in sortedByAgeThenName)
                Console.WriteLine($"{person.Name}, {person.Age}");

            Console.WriteLine();

            // 7. ThenByDescending: Secondary sort by Name descending
            var sortedByAgeThenNameDesc = people
                .OrderBy(p => p.Age)
                .ThenByDescending(p => p.Name);
            Console.WriteLine("Sorted by age, then by name (descending):");
            foreach (var person in sortedByAgeThenNameDesc)
                Console.WriteLine($"{person.Name}, {person.Age}");

            Console.WriteLine();

            // 8. Reverse: Reverse the list
            var reversedList = people.AsEnumerable().Reverse();
            Console.WriteLine("Reversed list:");
            foreach (var person in reversedList)
                Console.WriteLine($"{person.Name}, {person.Age}");

            Console.WriteLine();

            // 9. Distinct: Distinct names
            var distinctNames = people.Select(p => p.Name).Distinct();
            Console.WriteLine("Distinct names:");
            foreach (var name in distinctNames)
                Console.WriteLine(name);

            Console.WriteLine();

            // 10. Union: Union of two lists
            List<Person> morePeople = new List<Person>
            {
                new Person { Name = "Grace", Age = 27 },
                new Person { Name = "Alice", Age = 30 }
            };
            var unionList = people.Union(morePeople, new PersonComparer());
            Console.WriteLine("Union of lists (distinct persons):");
            foreach (var person in unionList)
                Console.WriteLine($"{person.Name}, {person.Age}");

            Console.WriteLine();

            // 11. Intersect: Common persons
            var intersectList = people.Intersect(morePeople, new PersonComparer());
            Console.WriteLine("Intersection of lists:");
            foreach (var person in intersectList)
                Console.WriteLine($"{person.Name}, {person.Age}");

            Console.WriteLine();

            // 12. Except: Persons in 'people' but not in 'morePeople'
            var exceptList = people.Except(morePeople, new PersonComparer());
            Console.WriteLine("Persons in 'people' but not in 'morePeople':");
            foreach (var person in exceptList)
                Console.WriteLine($"{person.Name}, {person.Age}");
        }

        // Custom comparer for Person to compare by Name and Age
        class PersonComparer : IEqualityComparer<Person>
        {
            public bool Equals(Person x, Person y)
            {
                return x.Name == y.Name && x.Age == y.Age;
            }

            public int GetHashCode(Person obj)
            {
                return (obj.Name + obj.Age).GetHashCode();
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

What does this example do?

  • Creates a list of Person objects.
  • Demonstrates filtering, projecting, sorting, reversing, deduplicating, set operations (Union, Intersect, Except) using LINQ operators.
  • Uses a custom comparer to compare Person objects based on Name and Age.

How to run?

  • Copy the code into a C# console application.
  • Run the program to see output demonstrating each LINQ operation.

Certainly! Here's a clear example demonstrating the use of Any, All, and Contains in LINQ with a list of Person objects:

using System;
using System.Collections.Generic;
using System.Linq;

namespace LinqQuantifiersExample
{
    class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }

    class Program
    {
        static void Main()
        {
            // Sample data
            List<Person> people = new List<Person>
            {
                new Person { Name = "Alice", Age = 30 },
                new Person { Name = "Bob", Age = 25 },
                new Person { Name = "Charlie", Age = 35 },
                new Person { Name = "David", Age = 40 }
            };

            // 1. Any: Are there any people older than 35?
            bool anyOlderThan35 = people.Any(p => p.Age > 35);
            Console.WriteLine($"Any person older than 35? {anyOlderThan35}");

            // 2. All: Are all people at least 25 years old?
            bool allAtLeast25 = people.All(p => p.Age >= 25);
            Console.WriteLine($"All people at least 25? {allAtLeast25}");

            // 3. Contains: Check if a specific person exists in the list
            Person targetPerson = new Person { Name = "Alice", Age = 30 };
            bool containsPerson = people.Contains(targetPerson, new PersonComparer());
            Console.WriteLine($"Contains Alice aged 30? {containsPerson}");
        }

        // Custom comparer for Person
        class PersonComparer : IEqualityComparer<Person>
        {
            public bool Equals(Person x, Person y)
            {
                return x.Name == y.Name && x.Age == y.Age;
            }

            public int GetHashCode(Person obj)
            {
                return (obj.Name + obj.Age).GetHashCode();
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Any: Checks if any person is older than 35.
  • All: Checks if all persons are at least 25.
  • Contains: Checks if a person with Name "Alice" and Age 30 exists in the list, using a custom comparer.

How to run:

  • Paste into a C# console app and run.
  • You will see output indicating whether each condition is true or false.

Certainly! Here's a clear example demonstrating all the aggregation operators (Count, Sum, Min, Max, Average) using a list of Person objects, focusing on the Age property:

using System;
using System.Collections.Generic;
using System.Linq;

namespace LinqAggregationExample
{
    class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }

    class Program
    {
        static void Main()
        {
            // Sample data
            List<Person> people = new List<Person>
            {
                new Person { Name = "Alice", Age = 30 },
                new Person { Name = "Bob", Age = 25 },
                new Person { Name = "Charlie", Age = 35 },
                new Person { Name = "David", Age = 40 }
            };

            // Count: Total number of people
            int totalPeople = people.Count();
            Console.WriteLine($"Total number of people: {totalPeople}");

            // Sum: Total age of all people
            int totalAge = people.Sum(p => p.Age);
            Console.WriteLine($"Sum of ages: {totalAge}");

            // Min: Youngest person's age
            int youngestAge = people.Min(p => p.Age);
            Console.WriteLine($"Youngest age: {youngestAge}");

            // Max: Oldest person's age
            int oldestAge = people.Max(p => p.Age);
            Console.WriteLine($"Oldest age: {oldestAge}");

            // Average: Average age
            double averageAge = people.Average(p => p.Age);
            Console.WriteLine($"Average age: {averageAge:F2}");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

What does this do?

  • Counts the total number of people.
  • Calculates the total sum of all ages.
  • Finds the minimum age.
  • Finds the maximum age.
  • Calculates the average age.

How to run:

  • Copy the code into a C# console application.
  • Execute to see the aggregation results.

Certainly! Here's a clear example demonstrating Skip, SkipWhile, Take, and TakeWhile with a list of Person objects based on their ages:

using System;
using System.Collections.Generic;
using System.Linq;

namespace LinqPartitioningExample
{
    class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }

    class Program
    {
        static void Main()
        {
            // Sample data
            List<Person> people = new List<Person>
            {
                new Person { Name = "Alice", Age = 30 },
                new Person { Name = "Bob", Age = 25 },
                new Person { Name = "Charlie", Age = 35 },
                new Person { Name = "David", Age = 40 },
                new Person { Name = "Eve", Age = 28 }
            };

            // Skip: Skip first 2 people
            var skippedPeople = people.Skip(2);
            Console.WriteLine("After skipping first 2 people:");
            foreach (var person in skippedPeople)
            {
                Console.WriteLine($"{person.Name} ({person.Age})");
            }

            // SkipWhile: Skip while age is less than 30
            var skipWhilePeople = people.SkipWhile(p => p.Age < 30);
            Console.WriteLine("\nSkip while age < 30:");
            foreach (var person in skipWhilePeople)
            {
                Console.WriteLine($"{person.Name} ({person.Age})");
            }

            // Take: Take first 3 people
            var takenPeople = people.Take(3);
            Console.WriteLine("\nFirst 3 people:");
            foreach (var person in takenPeople)
            {
                Console.WriteLine($"{person.Name} ({person.Age})");
            }

            // TakeWhile: Take while age is less than 35
            var takeWhilePeople = people.TakeWhile(p => p.Age < 35);
            Console.WriteLine("\nTake while age < 35:");
            foreach (var person in takeWhilePeople)
            {
                Console.WriteLine($"{person.Name} ({person.Age})");
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Skip(2): Skips the first two people in the list.
  • SkipWhile(p => p.Age < 30): Skips people while their age is less than 30.
  • Take(3): Takes the first three people.
  • TakeWhile(p => p.Age < 35): Takes people from the start while their age is less than 35.

How to run:

  • Copy into a C# console app.
  • Run to see how partitioning works.

Certainly! Here's a comprehensive example demonstrating First, FirstOrDefault, Last, LastOrDefault, Single, and SingleOrDefault with a list of Person objects:

using System;
using System.Collections.Generic;
using System.Linq;

namespace ElementOperationsExample
{
    class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }

    class Program
    {
        static void Main()
        {
            // Sample data
            List<Person> people = new List<Person>
            {
                new Person { Name = "Alice", Age = 30 },
                new Person { Name = "Bob", Age = 25 },
                new Person { Name = "Charlie", Age = 35 }
            };

            // First: Get the first person
            var firstPerson = people.First();
            Console.WriteLine($"First person: {firstPerson.Name} ({firstPerson.Age})");

            // FirstOrDefault: Get first person or default if list is empty
            var firstOrDefaultPerson = people.FirstOrDefault();
            Console.WriteLine($"FirstOrDefault person: {firstOrDefaultPerson?.Name ?? "None"}");

            // Last: Get the last person
            var lastPerson = people.Last();
            Console.WriteLine($"Last person: {lastPerson.Name} ({lastPerson.Age})");

            // LastOrDefault: Get last person or default if list is empty
            var lastOrDefaultPerson = people.LastOrDefault();
            Console.WriteLine($"LastOrDefault person: {lastOrDefaultPerson?.Name ?? "None"}");

            // Single: Get the only person in a list with exactly one element
            List<Person> singlePersonList = new List<Person> { new Person { Name = "Eve", Age = 28 } };
            var singlePerson = singlePersonList.Single();
            Console.WriteLine($"Single person: {singlePerson.Name} ({singlePerson.Age})");

            // SingleOrDefault: Get the only person or default if list is empty
            var singleOrDefaultPerson = new List<Person>().SingleOrDefault();
            Console.WriteLine($"SingleOrDefault (empty list): {singleOrDefaultPerson?.Name ?? "None"}");

            // Demonstrate exception with Single when multiple elements exist
            try
            {
                var invalidSingle = people.Single();
            }
            catch (InvalidOperationException ex)
            {
                Console.WriteLine($"Exception: {ex.Message}");
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

What does this code demonstrate?

  • Retrieves the first and last elements.
  • Retrieves the first and last element or default if the list is empty.
  • Retrieves a single element from a list that contains exactly one item.
  • Uses SingleOrDefault for an empty list.
  • Shows that Single() throws an exception if there are multiple elements.

How to run:

  • Copy into a C# console app.
  • Run to see the element operations in action.

Certainly! Here's a clear example demonstrating SequenceEqual to compare two sequences for equality:

using System;
using System.Collections.Generic;
using System.Linq;

namespace EqualityAndSetOperationsExample
{
    class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }

        // Override Equals and GetHashCode for proper comparison
        public override bool Equals(object obj)
        {
            if (obj is Person other)
            {
                return this.Name == other.Name && this.Age == other.Age;
            }
            return false;
        }

        public override int GetHashCode()
        {
            return HashCode.Combine(Name, Age);
        }
    }

    class Program
    {
        static void Main()
        {
            var list1 = new List<Person>
            {
                new Person { Name = "Alice", Age = 30 },
                new Person { Name = "Bob", Age = 25 }
            };

            var list2 = new List<Person>
            {
                new Person { Name = "Alice", Age = 30 },
                new Person { Name = "Bob", Age = 25 }
            };

            var list3 = new List<Person>
            {
                new Person { Name = "Alice", Age = 30 },
                new Person { Name = "Charlie", Age = 35 }
            };

            // Compare list1 and list2 (should be true)
            bool areEqual1 = list1.SequenceEqual(list2);
            Console.WriteLine($"list1 and list2 are equal: {areEqual1}");

            // Compare list1 and list3 (should be false)
            bool areEqual2 = list1.SequenceEqual(list3);
            Console.WriteLine($"list1 and list3 are equal: {areEqual2}");

            // Note: Without overriding Equals, SequenceEqual compares object references,
            // which would result in false unless the same object instances are used.
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • We override Equals and GetHashCode in the Person class to ensure value-based comparison.
  • SequenceEqual compares two sequences element-by-element for equality.
  • In this example, list1 and list2 are equal because they contain persons with identical Name and Age.
  • list1 and list3 are not equal because they differ in the second person's details.

How to run:

  • Copy into a C# console app.
  • Run to see the comparison results.

Certainly! Here's a comprehensive example demonstrating ToList, ToArray, ToDictionary, and AsEnumerable with a list of Person objects:

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConversionExamples
{
    class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    class Program
    {
        static void Main()
        {
            List<Person> people = new List<Person>
            {
                new Person { Id = 1, Name = "Alice" },
                new Person { Id = 2, Name = "Bob" },
                new Person { Id = 3, Name = "Charlie" }
            };

            // ToList: Convert to List<Person>
            List<Person> listOfPeople = people.ToList();
            Console.WriteLine("ToList:");
            foreach (var person in listOfPeople)
            {
                Console.WriteLine($"{person.Id}: {person.Name}");
            }

            // ToArray: Convert to Person[]
            Person[] arrayOfPeople = people.ToArray();
            Console.WriteLine("\nToArray:");
            foreach (var person in arrayOfPeople)
            {
                Console.WriteLine($"{person.Id}: {person.Name}");
            }

            // ToDictionary: Convert to Dictionary<int, Person> with Id as key
            Dictionary<int, Person> dictOfPeople = people.ToDictionary(p => p.Id);
            Console.WriteLine("\nToDictionary:");
            foreach (var kvp in dictOfPeople)
            {
                Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value.Name}");
            }

            // AsEnumerable: Treat the list as IEnumerable<Person>
            IEnumerable<Person> enumerablePeople = people.AsEnumerable();
            Console.WriteLine("\nAsEnumerable:");
            foreach (var person in enumerablePeople)
            {
                Console.WriteLine($"{person.Id}: {person.Name}");
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • ToList() creates a new List<Person> from the existing collection.
  • ToArray() creates an array of Person.
  • ToDictionary() converts the list into a Dictionary with Id as the key.
  • AsEnumerable() treats the list as an IEnumerable<Person> for LINQ operations or deferred execution.

How to run:

  • Copy into a C# console application.
  • Run to see each conversion in action.

Certainly! Here's a clear and practical example demonstrating GroupBy to group a list of persons by their age:

using System;
using System.Collections.Generic;
using System.Linq;

namespace GroupingExample
{
    class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }

    class Program
    {
        static void Main()
        {
            var people = new List<Person>
            {
                new Person { Name = "Alice", Age = 30 },
                new Person { Name = "Bob", Age = 25 },
                new Person { Name = "Charlie", Age = 30 },
                new Person { Name = "David", Age = 25 },
                new Person { Name = "Eve", Age = 35 }
            };

            // Group people by their age
            var groupedByAge = people.GroupBy(p => p.Age);

            // Display groups
            foreach (var group in groupedByAge)
            {
                Console.WriteLine($"Age Group: {group.Key}");
                foreach (var person in group)
                {
                    Console.WriteLine($" - {person.Name}");
                }
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • The GroupBy method groups Person objects based on their Age.
  • group.Key represents the age group.
  • The inner loop prints all names within each age group.

Output:

Age Group: 30
 - Alice
 - Charlie
Age Group: 25
 - Bob
 - David
Age Group: 35
 - Eve
Enter fullscreen mode Exit fullscreen mode

Certainly! Here's a clear example demonstrating both Join (inner join) and GroupJoin (group join / left outer join) with two related lists: Customers and Orders.

using System;
using System.Collections.Generic;
using System.Linq;

namespace JoiningExamples
{
    class Customer
    {
        public int CustomerId { get; set; }
        public string Name { get; set; }
    }

    class Order
    {
        public int OrderId { get; set; }
        public int CustomerId { get; set; }
        public string Product { get; set; }
    }

    class Program
    {
        static void Main()
        {
            var customers = new List<Customer>
            {
                new Customer { CustomerId = 1, Name = "Alice" },
                new Customer { CustomerId = 2, Name = "Bob" },
                new Customer { CustomerId = 3, Name = "Charlie" }
            };

            var orders = new List<Order>
            {
                new Order { OrderId = 101, CustomerId = 1, Product = "Laptop" },
                new Order { OrderId = 102, CustomerId = 1, Product = "Smartphone" },
                new Order { OrderId = 103, CustomerId = 2, Product = "Tablet" }
                // Note: Charlie has no orders
            };

            // 1. Inner Join using Join
            Console.WriteLine("Inner Join (Customers with their Orders):");
            var innerJoin = customers.Join(
                orders,
                customer => customer.CustomerId,
                order => order.CustomerId,
                (customer, order) => new
                {
                    CustomerName = customer.Name,
                    order.Product
                });

            foreach (var item in innerJoin)
            {
                Console.WriteLine($"{item.CustomerName} ordered {item.Product}");
            }

            // 2. Group Join (Left Outer Join)
            Console.WriteLine("\nGroup Join (Customers with their Orders, including customers with no orders):");
            var groupJoin = customers.GroupJoin(
                orders,
                customer => customer.CustomerId,
                order => order.CustomerId,
                (customer, customerOrders) => new
                {
                    CustomerName = customer.Name,
                    Orders = customerOrders
                });

            foreach (var group in groupJoin)
            {
                Console.WriteLine($"{group.CustomerName} has orders:");
                if (group.Orders.Any())
                {
                    foreach (var order in group.Orders)
                    {
                        Console.WriteLine($" - {order.Product}");
                    }
                }
                else
                {
                    Console.WriteLine(" - No orders");
                }
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Join: Finds matching pairs where CustomerId matches in both lists (inner join).
  • GroupJoin: Groups each customer with their orders, including customers with no orders (left outer join).

Sample Output:

Inner Join (Customers with their Orders):
Alice ordered Laptop
Alice ordered Smartphone
Bob ordered Tablet

Group Join (Customers with their Orders, including customers with no orders):
Alice has orders:
 - Laptop
 - Smartphone
Bob has orders:
 - Tablet
Charlie has orders:
 - No orders
Enter fullscreen mode Exit fullscreen mode

Certainly! Here's a clear example demonstrating AsQueryable and lazy evaluation with LINQ. This example shows how deferred execution works and how converting to IQueryable affects when the query executes.

using System;
using System.Collections.Generic;
using System.Linq;

namespace LazyEvaluationExample
{
    class Program
    {
        static void Main()
        {
            var numbers = new List<int> { 1, 2, 3, 4, 5 };

            // Convert to IQueryable for deferred execution
            IQueryable<int> queryableNumbers = numbers.AsQueryable();

            // Define a query with a filter
            var query = queryableNumbers.Where(n => n > 2);

            Console.WriteLine("Before enumeration, no execution occurs.");

            // Add a new number to the list after defining the query
            numbers.Add(6);

            // Enumerate the query - deferred execution occurs here
            Console.WriteLine("Query results after adding 6 to the list:");
            foreach (var num in query)
            {
                Console.WriteLine(num);
            }

            // Output explanation:
            // The query is executed when iterated, and since it's based on the list,
            // it includes the new number 6 added after the query was defined.
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • AsQueryable() converts the list into an IQueryable<int>, enabling deferred execution.
  • The LINQ query (Where) is not executed immediately.
  • When you iterate over query, the filtering happens at that moment, reflecting the current state of the list.
  • Adding 6 to the list before enumeration shows that the query includes the new element, demonstrating lazy evaluation.

Output:

Before enumeration, no execution occurs.
Query results after adding 6 to the list:
3
4
5
6
Enter fullscreen mode Exit fullscreen mode

Certainly! Here's a comprehensive example demonstrating Aggregate, DefaultIfEmpty, ElementAt, and ElementAtOrDefault with clear scenarios:

using System;
using System.Collections.Generic;
using System.Linq;

namespace OtherLinqMethodsExample
{
    class Program
    {
        static void Main()
        {
            var numbers = new List<int> { 10, 20, 30, 40, 50 };
            var emptyList = new List<int>();

            // 1. Aggregate: Sum of all numbers with custom operation
            int sum = numbers.Aggregate((total, next) => total + next);
            Console.WriteLine($"Sum of numbers: {sum}");

            // 2. DefaultIfEmpty: Provide default value if sequence is empty
            var defaultNumbers = emptyList.DefaultIfEmpty(100);
            Console.WriteLine("DefaultIfEmpty on empty list:");
            foreach (var num in defaultNumbers)
            {
                Console.WriteLine(num);
            }

            // 3. ElementAt: Get element at specific index (zero-based)
            int elementAtIndex2 = numbers.ElementAt(2); // 30
            Console.WriteLine($"Element at index 2: {elementAtIndex2}");

            // 4. ElementAtOrDefault: Get element at index or default if out of range
            int outOfRangeElement = numbers.ElementAtOrDefault(10); // default(int) = 0
            Console.WriteLine($"Element at index 10 or default: {outOfRangeElement}");

            // Demonstrate ElementAtOrDefault with a non-empty list
            int elementAtIndex4 = numbers.ElementAtOrDefault(4); // 50
            Console.WriteLine($"Element at index 4: {elementAtIndex4}");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Aggregate: Combines all elements using a specified operation—in this case, summing all numbers.
  • DefaultIfEmpty: If the sequence is empty, it returns a sequence with a default value (here, 100).
  • ElementAt: Retrieves the element at the specified zero-based index, throws an exception if out of range.
  • ElementAtOrDefault: Retrieves the element at the index or returns default value (0 for int) if the index is out of range.

Sample Output:

Sum of numbers: 150
DefaultIfEmpty on empty list:
100
Element at index 2: 30
Element at index 10 or default: 0
Element at index 4: 50
Enter fullscreen mode Exit fullscreen mode

Top comments (0)