Почему XmlDocument не работает в .NET 4?
Одна из областей, где я хотел бы использовать dynamic
, - это XML. Я думаю, что это упростило бы код обработки XML, и я считаю, что я видел несколько примеров этого, прежде чем С# 4 вышел, и он упомянул в этом ответе как одно из применений этой функции.
Итак, мой вопрос заключается в следующем: почему не был создан XmlDocument
(или XDocument
) динамический или почему нет нового класса для динамического XML-манипулирования в С# 4?
Это еще более странно для меня, когда я считаю, что в PowerShell XmlDocument
является динамическим, там работает код $xmlDoc.root.subnode.subsubnode
.
Ответы
Ответ 1
Учитывая некоторые из комментариев, позвольте мне предоставить альтернативный ответ. Первоначальный вопрос задал вопрос о том, почему XmlDocument не был динамическим в .NET 4. Хотя возможно добавить свойство "expando" для существующих классов документов xml через IDynamicMetaObjectProvider
, это, вероятно, является нетривиальным делом. Для того чтобы исходная объектная модель Xml из полностью динамической системы System.Xml потребовала некоторой обширной модификации инфраструктуры Xml и потребовала бы, чтобы IDynamicMetaObjectProvider был добавлен к каждому объекту, который задействован. Это включает XmlDocument, XmlElement, XmlAttribute, XmlNode и все другие типы содержимого xml, такие как комментарии, текстовые узлы и т.д. Кроме того, значительное количество инфраструктуры поддержки, внутренних типов и т.д., Которые участвуют в поиске и обработке элементы и атрибуты и значения также должны быть изменены (откройте Reflector и взгляните на System.Xml... более половины типов являются внутренними, и все они очень взаимозависимы друг с другом и доступными общедоступными типами.)
Также важно рассмотреть правильную область применения свойств expando для Xml в .NET. Вы остановились бы только на XmlDocument и связанных с ним типах? Или было бы более целесообразным включить XPath, Xml Schema и т.д.?
Чтобы ответить на исходный вопрос: "Почему isnt XmlDocument dynamic в .NET 4?", я думаю, что простой ответ таков: реализация полностью "динамических" API или, в случае с Xml здесь, API, которые обеспечивают расширение свойств произвольные xml-документы, далеки от тривиальной задачи. Учитывая этику работы Microsoft, логично понять, что они не будут легко подходить к такой задаче, и если они попытаются реализовать свойства expando для инфраструктуры Xml, я надеюсь и ожидаю, что это будет сделано с таким же вниманием и вниманием они дают остальной части .NET.
Ответ 2
Я удивлен количеством кажущейся авторитетной дискуссии без ответа. Ваш вопрос FANTASTIC. В нем конкретно рассматриваются такие удивительные вещи, для которых предназначалось ключевое слово 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;
}
}
И вот как бы вы назвали код. Обратите внимание, что это компилируется только в С# 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);
}
}
}
Я не могу взять на себя все это. Bamboo написал этот код для Boo еще в 2003 году. С# медленно получал функции, которые Boo имел в .NET в течение многих лет... сначала тип, а теперь стиль IQuackFu DynamicObject
. Как только они реализуют языковые макросы, чтобы вы могли создавать DSL, я думаю, что они поймают.
Я оставлю запись читателю новой версии XElement этого кода читателю.
Ответ 3
Скорее всего, они об этом не думали, и программисты обычно не сбивают с толку динамику повсюду: динамика - это бомба замедленного действия. Поймайте столько, сколько сможете во время компиляции...
Ответ 4
Поскольку XmlDocument предшествует genereics и исправлению, он сломает старый код.
Кроме того, XmlDocument указан как полууниверсальный.