Почему XmlDocument не является динамическим в .NET 4? - PullRequest
10 голосов
/ 23 июня 2010

Одной из областей, где я хотел бы видеть использование dynamic, является XML. Я думаю, что это облегчит написание кода для обработки XML, и я думаю, что видел несколько примеров этого до выхода C # 4 и упомянул в этом ответе как одно из применений этой функции.

Итак, мой вопрос таков: почему XmlDocument (или XDocument) не стал динамическим, или почему в C # 4 нет нового класса для динамического манипулирования XML?

Это еще более странно для меня, если учесть, что в PowerShell XmlDocument является динамическим , там работает код, подобный $xmlDoc.root.subnode.subsubnode.

Ответы [ 4 ]

12 голосов
/ 08 июля 2010

Я удивлен количеством, казалось бы, авторитетной дискуссии без ответа.Ваш вопрос фантастический.Он адресован ТОЧНО удивительным вещам, для которых предназначено ключевое слово 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;
   }
}

А вот как вы бы назвали код.Обратите внимание, что это компилируется только в 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);
      }
   }
}

Я не могу взять на себя всю ответственность за это. Bamboo написал этот код для Boo еще в 2003 году. C # постепенно получал функции, которыми Boo обладал в .NET в течение многих лет ... вывод первого типа, а теперь стиль IQuackFu DynamicObject.Как только они реализуют языковые макросы, чтобы вы могли создавать DSL, я думаю, что они наверстают упущенное.

Я оставлю запись новой версии XElement этого кода для читателя.

6 голосов
/ 04 июля 2010

Учитывая некоторые комментарии, позвольте мне дать альтернативный ответ.В первоначальном вопросе был задан вопрос, почему XmlDocument не был динамическим в .NET 4. Несмотря на то, что можно было бы добавить возможность свойства «expando» к существующим классам документов xml с помощью IDynamicMetaObjectProvider, это, вероятно, является нетривиальной задачей.Превращение исходной объектной модели Xml из System.Xml в полностью динамическое состояние потребует некоторой обширной модификации инфраструктуры Xml и потребует добавления IDynamicMetaObjectProvider в каждый участвующий объект.Это включает в себя XmlDocument, XmlElement, XmlAttribute, XmlNode и все другие типы содержимого xml, такие как комментарии, текстовые узлы и т. Д. Кроме того, значительное количество вспомогательной инфраструктуры, внутренних типов и т. Д., Которые участвуют в поиске и обработкеэлементы, атрибуты и значения также должны быть изменены (откройте Reflector и посмотрите на System.Xml ... более половины типов являются внутренними, и все они в значительной степени взаимозависимы друг с другом и доступными общедоступными типами.)

Важно также рассмотреть вопрос о том, как правильно реализовать свойства XML для расширения в .NET.Вы бы остановились только на XmlDocument и связанных с ним типах?Или было бы более целесообразно включить XPath, Xml Schema и т. Д.?

Чтобы ответить на первоначальный вопрос «Почему XmlDocument не является динамическим в .NET 4?», Я думаю, что простой ответ заключается в следующем: реализация полностью «динамических» API или, в случае с Xml, APIкоторые обеспечивают расширение свойств произвольных XML-документов, это далеко не тривиальная задача.Учитывая трудовую этику Microsoft, логично предположить, что они не будут легко подходить к такой задаче, и если они попытаются реализовать свойства expando для платформы Xml, я надеюсь и ожидаю, что это будет сделано с тем же уровнем внимательности и осторожности.они дают остальным .NET.

0 голосов
/ 04 июля 2010

Поскольку XmlDocument предшествует родовому состоянию и его исправление нарушит старый код.

Кроме того, XmlDocument указан как полу устаревший.

0 голосов
/ 04 июля 2010

Скорее всего, они не думали об этом, и программисты, как правило, недовольны тем, что повсеместно используют динамику: динамика - бомба замедленного действия. Поймай как можно больше во время компиляции ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...