Visual Studio Code Analysis Rule - "Do not expose generic lists"
Do not expose generic lists
IF all my methods, need to expose a collection, then 开发者_如何学PythonI need to user the Linq Extension .ToList(), almost everywhere I need to use lists, or user Collections in all my code.
If that’s the case, .ToList() is ignoring the rule right? Or is there a technique like copying the list o something to fix the violation and still return a list?
I disable that rule because I don't feel like it's a valid one. If you want to return a collection which contains an O(1)
count and is not a direct reference to an internal field, List<T>
is the best choice.
I don't deeply understand your case here but it sounds like you have a method which returns a LINQ query over some internal data. If that's the case then using a .ToList()
on the data is appropriate since you likely don't want future modifications of your internal fields to affect the return value of a method. In that case, there is no reason to not expose it as a List<T>
.
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 asList<T>
orT[]
whenIEnumerable<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 theCourse
class to be notified when the prerequisites change sinceList<T>
does not provide any modification callbacks. As such, usingList<T>
in this context is like having arbitrarily many public fields. On the other hand, we can subclassCollection<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...
Remember that all these rules were written for framework developers. Many of them are likely to be unsuitable unless you're also writing a framework.
You'll have to make a judgement call for every rule to see if it's valid for your circumstances. I like to use the analysis since it does find some bugs sometimes, but I always end up disabling certain rules (for example, I quite often have a catch Exception
as a final catch-all just because I need to log all kinds of errors even if they can't be handled).
精彩评论