Avoid return null;
from methods that return collections — return empty collections instead.
When a method returns a collection type, returning null
forces callers to check for null before using the collection.
This leads to defensive programming patterns and potential null reference exceptions.
This approach forces callers to handle null cases:
public List<User> GetActiveUsers()
{
if (!_userService.IsAvailable())
{
return null; // ⚠️ Forces null checks everywhere
}
return _userService.GetUsers().Where(u => u.IsActive).ToList();
}
Usage requires defensive programming:
var users = GetActiveUsers();
if (users != null) // ⚠️ Required null check
{
foreach (var user in users)
{
// Process user
}
}
Return empty collections instead of null:
public List<User> GetActiveUsers()
{
if (!_userService.IsAvailable())
{
return new List<User>(); // ✅ Empty collection
}
return _userService.GetUsers().Where(u => u.IsActive).ToList();
}
Usage is clean and safe:
var users = GetActiveUsers();
foreach (var user in users) // ✅ No null check needed
{
// Process user
}
The specific empty collection you return should match your method’s return type. Here’s a guide to common collection types and how to handle them.
Return Type | Recommended Return Statement |
---|---|
IEnumerable<T> | return Enumerable.Empty<T>(); |
ICollection<T> | return new List<T>(); |
IReadOnlyCollection<T> | return Array.Empty<T>(); |
IDictionary<K, V> | return new Dictionary<K, V>(); |
List<T> | return new List<T>(); |
T[] (Array) | return Array.Empty<T>(); |
With C# 12 and later, you can use collection expressions ([]
) to create an empty collection for any compatible type. The compiler infers the correct type from the method signature. This is now the recommended approach for its conciseness and clarity.
public List<User> GetActiveUsers()
{
if (!_userService.IsAvailable())
{
return []; // ✅ C# 12: Clean, concise, and type-safe.
}
return _userService.GetUsers().Where(u => u.IsActive).ToList();
}
To enforce this rule in your project, add the following to your .editorconfig
file:
# IDE0301: Simplify collection initialization
dotnet_diagnostic.IDE0301.severity = warning
This will make the compiler treat not using collection expressions as a warning, ensuring consistent code style across your team.