This rule can indeed be noisy, but there are some very valid reasons to avoid List<T>
in library code. It all depends on the context. Here are a few things to consider before disabling the rule or suppressing a given occurrence:
List<T>
is often a poor choice for input parameters as it forces callers to copy data unnecessarily. I have seen lots of code that declares parameters as List<T>
or T[]
when IEnumerable<T>
would suffice.
List<T>
can be a poor choice for properties as well. Consider the following alternatives:
public class Course {
public List<Course> Prerequisites { get; }
}
public class Course {
public Collection<Course> Prerequisites { get; }
}
The intention is that the caller can change a course's prerequistes by modifying the collection. In that case, if we use List<Course>
, there is no way for the Course
class to be notified when the prerequisites change since List<T>
does not provide any modification callbacks. As such, using List<T>
in this context is like having arbitrarily many public fields. On the other hand, we can subclass Collection<T>
and override its virtuals to be notified of changes.
List<T>
works best as a return value when complete ownership of the collection is transferred to the caller. This is why Enumerable.ToList()
is actually perfectly reasonable and it does not violate the spirit of the rule.
Now that I think about it, allowing List<T>
as a return value from methods, but continuing to flag List<T>
properties and parameters would probably greatly improve the rule's signal to noise ratio...