Одна из областей, где я хотел бы видеть использование dynamic
XML. Я думаю, что это заставило бы обработку XML кодировать более простой записать, и я полагаю, что видел некоторые примеры, на которых, прежде чем вышел C# 4, и это упоминается в этом ответе как одно из использования этой функции.
Так, мой вопрос - это: почему не был XmlDocument
(или XDocument
) сделанный динамичным, или почему не там некоторый новый класс для динамического управления XML в C# 4?
Это еще более странно для меня, когда я рассматриваю это в PowerShell, XmlDocument
является динамичным, код как $xmlDoc.root.subnode.subsubnode
работы там.
Учитывая некоторые комментарии, позвольте мне дать альтернативный ответ. В исходном вопросе спрашивалось, почему 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 и т. Д.?
Чтобы ответить на исходный вопрос: «Почему XmlDocument не является динамическим в .NET 4?», Я думаю, простой ответ таков: реализация полностью «динамических» API-интерфейсов или, в случае с Xml, API-интерфейсов, предоставляющих свойство расширение произвольных xml-документов, задача далеко не тривиальная.Учитывая рабочую этику Microsoft, логично, что они не подойдут к такой задаче легкомысленно, и если они попытаются реализовать свойства expando для Xml-фреймворка, я надеюсь и ожидаю, что это будет сделано с таким же вниманием и вниманием. они отдают остальную часть .NET.
Потому что XmlDocument появился раньше, чем genereics, и его исправление нарушит старый код.
Кроме того, XmlDocument числится как полуустаревший.
Скорее всего, они об этом не думали, и программисты обычно не очень довольны размещением динамики повсюду: динамика - это бомба замедленного действия. Поймайте как можно больше во время компиляции ...
Я удивлен количеством, казалось бы, авторитетного обсуждения без ответа. Ваш вопрос ФАНТАСТИЧЕСКИЙ. Он обращается ИМЕННО к тем удивительным вещам, для которого предназначалось ключевое слово 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);
}
}
}
Я не могу взять на себя всю ответственность за это. Бамбук написал этот код для Бу еще в 2003 году. C# медленно получает функции, которые Бу имел в .NET в течение многих лет... вывод первого типа, а теперь стиль IQuackFu DynamicObject
. Как только они реализуют языковые макросы, чтобы вы могли создавать DSL, я думаю, что они догонят.
Я оставлю написание более новой версии XElement этого кода читателю.