CSharper said:
I have a question on the last subject you are talking about. I am
using LINQ with XML a lot bit I know LINQ provides same amount
features to collection as well. But I don't understand how would you
replace a 'foreach' loop with a select? Do you mind to elobarate a
little bit for me?
Here's a good example: I've got a bunch of strings and I want to join them
as comma-separated values, taking care to escape them with quotes. I can do
it like this:
string csv;
var sb = new StringBuilder();
foreach (string s in myStrings) {
sb.Append('"' + s.Replace("\"", "\"\"") + '"' + ", ");
}
csv = sb.ToString(0, sb.Length > 0 ? sb.Length - 2 : 0);
This focuses on "how" rather than "what". This doesn't:
csv = string.Join(", ", myStrings.Select(s => '"' + s.Replace("\"",
"\"\"") + '"').ToArray());
Of course, I'm cheating because string.Join() already exists. If it didn't
we would probably write it as an extension method:
public static string Join(this IEnumerable<string> source, string
separator) {
var sb = new StringBuilder();
foreach (string s in source) {
sb.Append(s);
sb.Append(separator);
}
return sb.ToString(0, sb.Length > 0 ? sb.Length - 2 : 0);
}
Looks familiar, doesn't it? How does this avoid foreach? The benefit here is
that we only write down the "how" of joining one time, separating it from
escaping, and we can use this on every sequence of strings in the future.
While we're at it, let's write another function:
public static string DoubleEscape(this string s, char escapeCharacter) {
string escapeString = new string(escapeCharacter, 2);
return escapeCharacter + s.Replace(escapeCharacter, escapeString) +
escapeCharacter;
}
And now our CSV-encoding looks like this:
csv = myStrings.Select(s => s.DoubleEscape('"')).Join(", ");
You can't get much clearer than that.
Of course, you can't literally replace every foreach loop with a select, nor
is that desireable. If you really have to invoke methods on objects to
change it, a foreach loop is the way to go. Even if you could use LINQ for
that, you wouldn't want to, since LINQ should be used free of side effects.