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