Do Not Expose Generic Lists
ID |
csharp.do_not_expose_generic_lists |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Best Practice |
Language |
CSharp |
Tags |
api_design, best_practice |
Description
Reports public or protected API members whose declared type is System.Collections.Generic.List<T>.
The .NET design guidelines recommend exposing an interface instead, so callers depend on the
contract rather than the specific implementation.
Rationale
Returning a concrete List<T> leaks the implementation. Callers can mutate the
collection, the implementation cannot later swap to a different backing structure
(immutable list, array segment, lazy view) without a breaking change, and read-only
intent cannot be communicated. IList<T>, ICollection<T> and IReadOnlyList<T> model
the relevant contracts directly.
public class Inventory
{
public List<string> Items { get; } // FLAW
public List<string> Fetch(int n) => new(); // FLAW
public IReadOnlyList<string> History { get; } = new List<string>(); // OK
public IList<string> Categories { get; } // OK
public IList<string> Search(string term) => new List<string>(); // OK
}