How to Use LINQ Single and SingleOrDefault in C#
In C#,
Single returns the only element in a collection that matches a condition and throws an exception if there is not exactly one match. SingleOrDefault returns the single matching element or a default value (usually null for reference types) if none is found, but throws if more than one match exists.Syntax
Single() and SingleOrDefault() are LINQ extension methods used on collections to find exactly one element that matches a condition.
Single(): Returns the single matching element or throws if zero or multiple matches.SingleOrDefault(): Returns the single matching element or default value if none found; throws if multiple matches.
csharp
var singleItem = collection.Single(predicate); var singleOrDefaultItem = collection.SingleOrDefault(predicate);
Example
This example shows how to use Single and SingleOrDefault to find elements in a list of numbers.
csharp
using System; using System.Linq; using System.Collections.Generic; class Program { static void Main() { List<int> numbers = new List<int> { 1, 2, 3, 4, 5 }; // Single: find the number 3 int singleNumber = numbers.Single(n => n == 3); Console.WriteLine($"Single found: {singleNumber}"); // SingleOrDefault: find number 10 (not in list) int singleOrDefaultNumber = numbers.SingleOrDefault(n => n == 10); Console.WriteLine($"SingleOrDefault found: {singleOrDefaultNumber}"); // SingleOrDefault: find number 2 int singleOrDefaultNumber2 = numbers.SingleOrDefault(n => n == 2); Console.WriteLine($"SingleOrDefault found: {singleOrDefaultNumber2}"); } }
Output
Single found: 3
SingleOrDefault found: 0
SingleOrDefault found: 2
Common Pitfalls
Common mistakes include:
- Using
Singlewhen the collection has zero or multiple matches, causing exceptions. - Expecting
SingleOrDefaultto return null for value types; it returns the default value (e.g., 0 for int). - Not handling exceptions from
Singlewhen multiple matches exist.
Always ensure your data has exactly one matching element before using Single.
csharp
using System; using System.Linq; using System.Collections.Generic; class Program { static void Main() { List<int> numbers = new List<int> { 1, 2, 2, 3 }; // This will throw InvalidOperationException because there are two '2's try { int singleNumber = numbers.Single(n => n == 2); } catch (InvalidOperationException ex) { Console.WriteLine("Exception caught: " + ex.Message); } // Correct way: use SingleOrDefault and check for duplicates manually if needed int singleOrDefaultNumber = numbers.SingleOrDefault(n => n == 2); Console.WriteLine($"SingleOrDefault found: {singleOrDefaultNumber}"); } }
Output
Exception caught: Sequence contains more than one matching element
SingleOrDefault found: 2
Quick Reference
| Method | Returns | Throws Exception When | Default Value if None Found |
|---|---|---|---|
| Single() | The only matching element | No matches or more than one match | N/A |
| SingleOrDefault() | The only matching element or default | More than one match | Default(T) (e.g., null for reference types or 0 for value types) |
Key Takeaways
Use Single() when you expect exactly one matching element and want an exception if not.
Use SingleOrDefault() to get a single element or a default value if none exists, but it throws if multiple matches occur.
SingleOrDefault returns default(T) for value types, not null.
Always handle exceptions or check data to avoid runtime errors with Single and SingleOrDefault.
These methods help enforce data uniqueness in queries.