Ich bin überrascht über die Menge der scheinbar autoritativen Diskussion ohne Antwort. Deine Frage ist FANTASTISCH. Es spricht GENAU die Art von tollen Dingen an, für die das Schlüsselwort dynamic
bestimmt war. Das Problem ist, dass nicht viele Leute wirklich wissen, wie man es in vollen Zügen nutzt.
Während MS die dynamischen XML-Objekte für uns nicht erstellt hat, gaben sie uns die Werkzeuge, um es selbst mit der Klasse DynamicObject zu tun. Hier ist eine Möglichkeit zu tun, was Sie mit der alten XmlDocument
Klasse verlangen.
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;
}
}
Und hier ist, wie Sie den Code nennen würden.Beachten Sie, dass dies nur in C# 4.0 kompiliert wird.
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);
}
}
}
Ich kann nicht all den Kredit dafür nehmen. Bamboo wrote this code für Boo im Jahr 2003. C# hat seit Jahren langsam die Funktionen, die Boo in .NET gehabt hat, bekommen ... zuerst Inferenz und jetzt den IQuackFu-Stil DynamicObject
. Sobald sie Sprachmakros implementiert haben, damit Sie DSLs erstellen können, werden sie meiner Meinung nach etwas aufholen.
Ich werde die neuere XElement-Version dieses Codes an den Leser schreiben.
Wenn irgendein Typ geändert würde, wäre es XDocument, nicht XmlDocument. –
Ist die Antwort auf diese Frage auch speziell für C#? –
AFAIK, 'dynamic' ist eine Eigenschaft von C#, also ja, spezifisch für C#. – svick