What is the proper ForAll
method for the Dictionary
object? I am learning the Linq type iteration (method 1 below), but do not getting it to work. The old foreach
loop works (method 2 below). Despite many answers on similar questions, e.g. this question, I do not see a Linq iteration solution.
The Dictionary seems to have methods to get all Keys or all Values, usable in the Linq iteration, but not to get all KeyValuePairs. Strange!
I did some fiddling with GetEnumeration()
, but without much luck.
The AsParallel()
method seemed the solution, found here, but with me I only got a build error: Dictionary does not contain a definition for AsParallel .
One could argue that Method 2 does not have so much more lines of source, but to me the Linq iteration of Method 1 is still more simple, more direct, more elegant.
Is there still an easy way to make Method 1 work?
Version: .Net Framework 4.5.2
using System.Linq;//AsParallel, ToList
using System.Collections.Generic;//Dictionary
using System.Xml.Linq;//XElement
using System.IO;//Path, Dir, File
public Dictionary<string, string> DictUserConfig = new Dictionary<string, string>();
public void SaveFile(string FileName)
{
XDocument XDConf = new XDocument(new XDeclaration("1.0", "utf-8", "yes"));
#if true//method 1: problem: Dictionary does not have a .ForAll or .ForEach method, or .GetEnumerator().ForAll(x => ...)
XDConf.Add(
new XElement("settings",
DictUserConfig.ForEach(x =>
new XElement("add",
new XAttribute("key", x.Key),
new XAttribute("value", x.Value)))));
#else//method 2: works
XElement XSettings = new XElement("settings");
XDConf.Add(XSettings);
foreach (KeyValuePair<string, string> x in DictUserConfig)
{
XSettings.Add(
new XElement("add",
new XAttribute("key", x.Key),
new XAttribute("value", x.Value)));
}
#endif
XDConf.Save(FileName);
return;
}
Update:
I discovered one problem: missing using System.Linq
, removed some time ago when I didn't need that. Discovered by testing the several useful comments on my post.
Now the problem is more easily summarized as:
This works:
DictUserConfig.ToList<KeyValuePair<string, string>>().ForEach(x => Console.WriteLine(x.Key + x.Value));
DictUserConfig.AsParallel().ForAll(x => Console.WriteLine(x.Key + x.Value));
But this does not work:
XElement XE1 = (XElement)DictUserConfig.ToList<KeyValuePair<string, string>>().ForEach(x => new XElement(x.Key, x.Value));
XElement XE2 = DictUserConfig.AsParallel().ForEach(x => new XElement(x.Key, x.Value));
And the reason is, I suppose, that ToList and AsParallel do not return the result of the ForEach back to the this
. The build error is: cannot convert void to object (or XElement). So the only 'solution' seems to create ForEach myself using the one-liner, which is already showing as a solution, but taking care to return an XElement object.
After testing the final answer, I would like to note that the discussion is not about the relative values of ForEach versus foreach, but that this obscured the real solution of Select. Also, foreach is more the Fortran way of making something happen, and ForEach, and especially Select, rather about what you want to achieve.
I would like to thank everyone for the comments and answers, of which I learned something today.