I tried this simple query on LinqPad and scratched by head as to why the second query works but the first one just does not alter the list(descen).
- How do i make it work. I use this code to clone and modify xml attribute,value
Fails
var doc = XElement.Parse("<Root><Descendants>Welcome</Descendants><Descendants>Stack</Descendants><Descendants>Overflow</Descendants></Root>");
var descen = (from des in doc.Descendants("Descendants") select new XElement(des));
foreach (var desc in descen)
{
desc.Value += DateTime.UtcNow;
}
descen.Dump();
doc.Dump();
Works
var doc = XElement.Parse("<Root><Descendants>Welcome</Descendants><Descendants>Stack</Descendants><Descendants>Overflow</Descendants></Root>");
var descen = (from des in doc.Descendants("Descendants") select new XElement(des));
foreach (var desc in doc.Descendants("Descendants"))
{
desc.Value += DateTime.UtcNow;
}
descen.Dump();
doc.Dump();
Stall’s my PC ?? WTH
var doc = XElement.Parse("<Root><Descendants>Welcome</Descendants><Descendants>Stack</Descendants><Descendants>Overflow</Descendants></Root>");
var descen = (from des in doc.Descendants("Descendants") select des);
foreach (var desc in descen)
{
desc.Value += DateTime.UtcNow;
}
var instance = from t in descen select new XElement(t);
doc.Elements("Descendants").LastOrDefault().AddAfterSelf(instance);
descen.Dump();
In the first query,
descenis a projection from existing elements to new elements. It’s lazily evaluated – each time you iterate over it, it will create new elements.In the first case, you iterate over
descen, and modify the new elements as you go. However, those modified elements are effectively thrown away very soon after they’re created – they’re not part of the original document.In the second case, you modify the elements in the original document, so when you iterate over
descen, it will create a copy of the modified elements, and displays those.EDIT: If you want to change
descenbut not the original document, you can just addToList()at the end of the initialization part ofdescen. For example:Or, more readably IMO:
The reason your final code hangs is that as
AddAfterSelfiterates overinstance, it’s adding elements… but those elements are then part of the document, which means they’re part of thedescenquery, which means they’re part of theinstancequery… so iterating overinstancewill never complete.