Practical examples of C# lists and list operations for modern C#
Real‑world examples of C# lists and list operations
Let’s start with concrete, realistic code. These examples of C# lists and list operations assume modern C# (C# 10+), but they work fine in most recent .NET versions.
Basic example of creating and populating a List
The most common example of List<T> is a simple collection of values you append to over time:
using System;
using System.Collections.Generic;
public class BasicListExample
{
public static void Run()
{
// Create a list of integers
var scores = new List<int>();
// Add items
scores.Add(95);
scores.Add(82);
scores.Add(100);
// Add multiple items at once
scores.AddRange(new[] { 76, 88, 91 });
Console.WriteLine($"Count: {scores.Count}");
Console.WriteLine("Scores:");
foreach (var score in scores)
{
Console.WriteLine(score);
}
}
}
This is one of the best examples for beginners: you see Add, AddRange, Count, and foreach in a single, compact snippet.
Examples of C# lists and list operations with objects
Real applications rarely store just integers or strings. You typically work with domain objects. Here’s an example of C# lists and list operations using a Customer class:
public record Customer(int Id, string Name, bool IsActive, DateTime CreatedAt);
public class CustomerListExample
{
public static void Run()
{
var customers = new List<Customer>
{
new(1, "Alice", true, DateTime.UtcNow.AddDays(-10)),
new(2, "Bob", false, DateTime.UtcNow.AddDays(-30)),
new(3, "Carlos", true, DateTime.UtcNow.AddDays(-1)),
};
// Find a single customer
var alice = customers.Find(c => c.Name == "Alice");
// Filter active customers
var active = customers.FindAll(c => c.IsActive);
// Remove inactive customers
customers.RemoveAll(c => !c.IsActive);
Console.WriteLine($"Active customers count: {customers.Count}");
}
}
This example of object lists shows how Find, FindAll, and RemoveAll help you keep your collection in a clean, business‑ready state.
Examples of list operations with LINQ in modern C
In 2024–2025, LINQ is standard practice in C# codebases. Many of the best examples of C# lists and list operations involve LINQ because it makes filtering, sorting, and projection more readable.
Filtering and projecting data from a List
Imagine you’ve just called a web API and parsed a JSON response into a list of DTOs. Now you want only the active users and just their emails:
using System.Linq;
public record UserDto(int Id, string Email, bool IsActive);
public class LinqListExample
{
public static void Run()
{
var users = new List<UserDto>
{
new(1, "alice@example.com", true),
new(2, "bob@example.com", false),
new(3, "carl@example.com", true)
};
var activeEmails = users
.Where(u => u.IsActive)
.Select(u => u.Email)
.ToList();
foreach (var email in activeEmails)
{
Console.WriteLine(email);
}
}
}
This is one of those real examples you see in API‑heavy services: take a list, filter it, and project it into a simpler list for downstream processing.
Sorting and custom comparison examples
Sorting is another everyday operation. Here’s an example of C# lists and list operations that sorts by multiple fields:
public record Product(int Id, string Name, decimal Price, int Stock);
public class SortingListExample
{
public static void Run()
{
var products = new List<Product>
{
new(1, "Laptop", 1299.99m, 5),
new(2, "Mouse", 29.99m, 50),
new(3, "Monitor", 199.99m, 10),
new(4, "Laptop", 1099.99m, 3)
};
// Sort by Name, then by Price ascending
var sorted = products
.OrderBy(p => p.Name)
.ThenBy(p => p.Price)
.ToList();
foreach (var product in sorted)
{
Console.WriteLine($"{product.Name} - {product.Price:C}");
}
}
}
If you prefer not to use LINQ, you can use List<T>.Sort with a custom comparison delegate:
products.Sort((a, b) => a.Price.CompareTo(b.Price));
This pattern shows up constantly in UI grids, reports, and API responses that need predictable ordering.
Performance‑aware examples of C# lists and list operations
As data volumes grow, performance matters. Microsoft’s own documentation points out that List<T> is backed by an array and grows as needed, which can cause allocations when capacity is exceeded. You can read more about collection performance in the official .NET docs at learn.microsoft.com.
Pre‑allocating capacity for large imports
When you know roughly how many items you’ll load, pre‑allocating capacity helps avoid repeated resizing:
public class CapacityExample
{
public static void Run(int expectedCount)
{
// Pre-allocate capacity for a bulk import
var records = new List<string>(capacity: expectedCount);
for (var i = 0; i < expectedCount; i++)
{
records.Add($"Record-{i}");
}
Console.WriteLine($"Final count: {records.Count}");
Console.WriteLine($"Capacity: {records.Capacity}");
}
}
In high‑throughput services—think telemetry processing or log aggregation—this example of tuning list capacity can cut GC pressure and improve latency.
Using AsReadOnly to protect internal lists
Sometimes you want to expose a list for reading but prevent callers from mutating it directly. Here’s a pattern you’ll see in well‑structured domain models:
using System.Collections.ObjectModel;
public class Order
{
private readonly List<OrderLine> _lines = new();
public ReadOnlyCollection<OrderLine> Lines => _lines.AsReadOnly();
public void AddLine(OrderLine line) => _lines.Add(line);
}
public record OrderLine(string Sku, int Quantity);
This is one of the best examples of using List<T> internally while exposing a safer, read‑only view to the outside world.
Examples include async and parallel scenarios
Modern C# in 2024–2025 often means async I/O and parallel processing. Lists still sit at the center of those patterns.
Collecting results from async operations
Suppose you’re calling multiple HTTP endpoints and collecting results into a list:
using System.Net.Http;
using System.Threading.Tasks;
public class AsyncListExample
{
private static readonly HttpClient _http = new();
public static async Task RunAsync()
{
var urls = new List<string>
{
"https://example.com/api/users",
"https://example.com/api/orders",
"https://example.com/api/products"
};
var tasks = urls
.Select(url => _http.GetStringAsync(url))
.ToList();
var responses = await Task.WhenAll(tasks);
Console.WriteLine($"Received {responses.Length} responses.");
}
}
This example of using lists with async calls shows how naturally List<T> works with Task and LINQ in modern service code.
Parallel processing with lists
For CPU‑bound work, you might process a list in parallel. While List<T> itself is not thread‑safe for concurrent writes, it’s fine for concurrent reads if no thread mutates it.
using System.Threading.Tasks;
public class ParallelListExample
{
public static void Run()
{
var numbers = Enumerable.Range(1, 1_000).ToList();
Parallel.ForEach(numbers, n =>
{
var squared = n * n;
// Do something with squared value
});
}
}
In data‑processing pipelines, this pattern is a common example of squeezing more throughput out of a simple list.
Comparing List to other collections: practical examples
You can’t talk about examples of C# lists and list operations without at least touching on when a list is the wrong tool.
Example of List vs. HashSet
If you frequently check membership (Contains) on a large collection, a HashSet<T> is often faster than a List<T> because it uses hashing instead of linear search.
public class MembershipExample
{
public static void Run()
{
var ids = new List<int> { 1, 2, 3, 4, 5 };
var idSet = new HashSet<int>(ids);
Console.WriteLine(ids.Contains(5)); // O(n)
Console.WriteLine(idSet.Contains(5)); // O(1) on average
}
}
This is a real example you’ll hit when optimizing hot paths in APIs or batch jobs.
Example of List vs. Array
Arrays (T[]) can be slightly faster and use less memory, but they’re fixed‑size. Lists trade a little overhead for the ability to grow and shrink.
public class ArrayVsListExample
{
public static void Run()
{
int[] fixedSize = new int[3];
fixedSize[0] = 10;
var flexible = new List<int>();
flexible.Add(10);
flexible.Add(20);
flexible.Remove(10);
}
}
In performance‑critical libraries—such as numerical code or low‑level parsers—you’ll often see arrays. For most application code, examples of C# lists and list operations dominate because they’re easier to work with.
Data‑driven examples: trends in C# list usage (2024–2025)
If you scan modern .NET repositories on GitHub or read recent talks from Microsoft’s .NET team, you’ll notice a few patterns:
List<T>is still the default in business applications for in‑memory collections.- LINQ‑based list operations are everywhere: filtering, sorting, grouping, and projections are almost always expressed with LINQ.
- Performance‑sensitive code often uses
List<T>as a staging area, then converts to arrays for final processing.
While there isn’t a government dataset on C# list usage (this is more of an industry practice issue), you can see similar data‑structure tradeoffs discussed in algorithm courses from universities like Harvard’s CS50, which covers lists, arrays, and hash tables in a language‑agnostic way.
For general programming and computing literacy, resources like the U.S. Department of Education’s ed.gov site and major university CS curricula provide context on why dynamic collections such as lists are favored in many real‑world scenarios.
FAQ: examples of C# lists and list operations
Q: Can you give a simple example of filtering a C# list by property?
Yes. Suppose you have a list of orders and you want only the paid ones:
public record OrderDto(int Id, bool IsPaid);
var orders = new List<OrderDto>
{
new(1, true),
new(2, false),
new(3, true)
};
var paidOrders = orders.Where(o => o.IsPaid).ToList();
This is one of the most common examples of filtering in business apps.
Q: What is an example of converting a List to an array?
var list = new List<string> { "alpha", "beta", "gamma" };
string[] array = list.ToArray();
You’ll see this in libraries that expose arrays for performance while using lists internally during construction.
Q: How do I remove items safely while iterating a list?
Avoid removing items inside a foreach. Either use RemoveAll:
numbers.RemoveAll(n => n < 0);
or iterate backwards with a for loop:
for (int i = numbers.Count - 1; i >= 0; i--)
{
if (numbers[i] < 0)
numbers.RemoveAt(i);
}
Both are standard examples include patterns you’ll see in production code.
Q: Are there best examples of when not to use List
Yes. If you need fast key‑based lookups, prefer Dictionary<TKey,TValue> or HashSet<T>. If you need thread‑safe concurrent writes, look at ConcurrentBag<T> or ConcurrentDictionary<TKey,TValue> in System.Collections.Concurrent. These are real examples where List<T> can become a bottleneck or a source of subtle bugs.
Q: Do these examples of C# lists and list operations apply to .NET 8 and later?
They do. List<T> has been stable for years, and the patterns shown here work across .NET 6, 7, 8, and upcoming versions. Newer runtimes bring performance improvements under the hood, but the public API and the examples of examples of C# lists and list operations you’ve seen remain valid.
In short, if you understand these examples of C# lists and list operations—basic creation, LINQ queries, sorting, capacity tuning, async usage, and comparisons with other collections—you’re in a strong position to write clean, modern C# that behaves well under real workloads.
Related Topics
Practical examples of polymorphism in C++: function overloading
Best examples of dynamic memory allocation in C++: new and delete
Practical examples of C# variable declaration and initialization examples
Modern examples of C++ operator overloading: custom operators examples that actually matter
Best examples of C# conditional statements: examples & explanations
Real‑world examples of C# exception handling: 3 practical patterns every developer should know
Explore More C++ Code Snippets
Discover more examples and insights in this category.
View All C++ Code Snippets