我最近发现臭名昭着的Jon Skeet关于使用LINQ to XML的帖子.这段特殊代码引起了我的注意:
// Customers is a List<Customer>
XElement customersElement = new XElement("customers",
customers.Select(c => new XElement("customer", //This line is "magic"
new XAttribute("name", c.Name),
new XAttribute("lastSeen", c.LastOrder)
new XElement("address",
new XAttribute("town", c.Town),
new XAttribute("firstline", c.Address1),
// etc
));
Run Code Online (Sandbox Code Playgroud)
我决定在我的应用程序中自己测试它,我有一个foreach循环设置如下:
foreach (var kvp in m_jobs) { //m_jobs is a Dictionary<string,Job>
m_xmlDoc.Root.Element("SCHED_TABLE").Add(
kvp.Value.GenerateXmlNode())
);
}
Run Code Online (Sandbox Code Playgroud)
我修改为:
m_xmlDoc.Root.Element("SCHED_TABLE").Add(
m_jobs.Select(job => job.Value.GenerateXmlNode())
};
Run Code Online (Sandbox Code Playgroud)
其中GenerateXmlNode()是为特定作业项生成适当XML标记的方法.我不确定会发生什么,但是它看起来和我的foreach循环完全一样.我不太明白的是为什么?!此外,这被认为是LINQ的"滥用"还是"功能"?
为清晰起见编辑:我知道.Select将返回一个IEnumerable,其中包含我要求的内容,但我并没有明确地枚举它.我理解.Add是如何工作的,因为它接受了可变数量的参数,但同样,我没有明确枚举传递这些参数.那么......它怎么还能用呢?
这个XElement.Add方法看起来像这样:
public void Add(object content)
{
if (content is IEnumerable)
{
foreach (object child in (IEnumerable)content)
Add(child);
}
else
{
//process individual element
}
}
Run Code Online (Sandbox Code Playgroud)
因此,虽然从公共接口不清楚Add,您可以传递一个项目序列或单个项目,它将确定它在运行时它和相应的行为.
没有魔力; 该Add方法接受a object或a params object[]- 并且在内部它只是检查每个输入的一系列常见场景,包括IEnumerable等.然后它只是展开序列,添加它发现的子元素/属性.LINQ返回(在此场景中)IEnumerable序列Select,使其完全可用.
| 归档时间: |
|
| 查看次数: |
394 次 |
| 最近记录: |