svi*_*ick 10 xml dynamic c#-4.0
我希望看到使用的一个领域dynamic
是XML.我认为它会使XML处理代码更容易编写,我相信在C#4出现之前我已经看到了一些例子,并且在这个答案中提到它是此功能的一个用途.
所以,我的问题是:为什么不是XmlDocument
(或XDocument
)动态,或者为什么在C#4中没有动态XML操作的新类?
这对我来说更加奇怪,当我认为在PowerShell中,它XmlDocument
是动态的,代码就像$xmlDoc.root.subnode.subsubnode
在那里工作一样.
mat*_*mc3 12
在没有答案的情况下,我对看似权威的讨论感到惊讶.你的问题很神奇.它完全解决了dynamic
关键字所针对的那种令人敬畏的事情.麻烦的是,并没有很多人真正知道如何充分利用它.
虽然MS没有为我们构建动态XML对象,但它们确实为我们提供了使用DynamicObject类自行完成的工具.这是与老XmlDocument
班级一起做的事情的一种方式.
public class DynamicXmlElement : DynamicObject {
XmlElement _xmlEl;
public DynamicXmlElement(string xml) {
var xmldoc = new XmlDocument();
xmldoc.LoadXml(xml);
_xmlEl = xmldoc.DocumentElement;
}
public DynamicXmlElement(XmlElement el) {
_xmlEl = el;
}
public override bool TrySetMember(SetMemberBinder binder, object value) {
return false;
}
public override bool TryGetMember(GetMemberBinder binder, out object result) {
XmlElement el = (XmlElement)_xmlEl.SelectSingleNode(binder.Name);
if (el != null) {
// wrap the element we found in a new DynamicXmlElement object
result = new DynamicXmlElement(el);
return true;
}
else if (binder.Name == "root") {
// special case for handling references to "root"
result = new DynamicXmlElement(_xmlEl.OwnerDocument.DocumentElement);
return true;
}
else {
// feel free to change this to prevent having accidental null reference issues
// by just setting the result to a DynamicXmlElement with a null element and
// handling _xmlEl == null at the start of this method
result = null;
return false;
}
}
public override string ToString() {
return _xmlEl.InnerText;
}
}
Run Code Online (Sandbox Code Playgroud)
这就是你如何调用代码.请注意,这仅在C#4.0中编译.
namespace ConsoleApplication4 {
class Program {
static void Main(string[] args) {
var xmlstr = "<r><subnode><subsubnode>ABCs of dynamic classes</subsubnode></subnode></r>";
dynamic xml = new DynamicXmlElement(xmlstr);
Console.WriteLine(xml.subnode.root.subnode.subsubnode); // take the long way around...
Console.ReadKey(true);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我不能完全相信这一点. Bamboo在2003年为Boo 编写了这段代码 .C#已经慢慢获得了Boo多年来在.NET中拥有的功能......第一种类型的推理,现在是IQuackFu风格DynamicObject
.一旦他们实现了语言宏以便你可以制作DSL,我认为他们已经赶上了.
我将把这个代码的新风格XElement版本留给读者.
鉴于一些评论,让我提供一个替代答案.最初的问题是为什么XmlDocument在.NET 4中不是动态的.虽然有可能通过现有的xml文档类添加"expando"属性功能IDynamicMetaObjectProvider
这样做可能是一件非常重要的事情.使System.Xml中的原始Xml对象模型完全动态化需要对Xml框架进行一些大量修改,并且需要将IDynamicMetaObjectProvider添加到所涉及的每个对象中.这包括XmlDocument,XmlElement,XmlAttribute,XmlNode以及所有其他xml内容类型,如注释,文本节点等.此外,还有大量的支持基础结构,内部类型等,它们涉及查找和处理元素,属性和值也需要修改(打开Reflector,看看System.Xml ......超过一半的类型是内部的,它们彼此高度相互依赖,并且可用的公共类型.)
考虑在.NET中实现Xml的expando属性的适当范围也很重要.你会停止在XmlDocument和相关类型?或者包含XPath,Xml Schema等更合适吗?
为了回答原始问题,"为什么在.NET 4中没有动态的XmlDocument?",我认为简单的答案是:实现完全"动态"API,或者在Xml的情况下,提供任意属性扩展的API xml文档,远非繁琐的任务.鉴于微软的职业道德,从逻辑上讲,他们不会轻易接近这样的任务,如果他们试图为Xml框架实现expando属性,我希望并期望它能够以同样的谨慎关注和关注来完成他们给.NET的其余部分.