The problem with IEnumerable<T>
that is in general case it is not consistent, e.g. when we read from outer source (like file, RDBMS table, COM port etc.)
IEnumerable<string> lines = File
.ReadLines(@"c:\...")
...
we can have different data when we enumerate lines
second time (file, table can be changed).
To avoid this possible inconsistency you can materialize the enumeration:
// Materialization can be required, but
// let's avoid overhead if lines is already a collection.
// From now on source is a collection; it doesn't change between loops
var source = lines as IReadOnlyCollection<string> ?? lines.ToList();
...
// 1st loop
foreach(var data in source.ParseAsEnumberable(Delimiter, StringQualifer)) {
...
}
...
// 2nd loop over the very same collection
foreach(var item in source) {
...
}
Edit: if you absolutely sure that you have to loop over enumeration several times and you are not going to have problems with inconsistency, you can suppress the warning with a help of pragma
:
//TODO: Provide justification why it is safe to break the rule here
// E.g. "The file is locked and can't be modified"
#pragma warning disable CA1851
foreach (var data in lines.ParseAsEnumberable(Delimiter, StringQualifer)) {
...
}
...
foreach (var item in lines) {
...
}
// Don't forget to restore:
// we've adjusted just one exception from the general rule
#pragma warning restore CA1851