2010-06-23 4 views
10

Einer der Bereiche, in denen ich die Verwendung von dynamic sehen möchte, ist XML. Ich denke, es würde XML-Code einfacher zu schreiben machen und ich glaube, ich sah einige Beispiele, bevor C# 4 herauskam und es in this answer als eine der Nutzungen dieser Funktion erwähnt.Warum ist XmlDocument in .NET 4 nicht dynamisch?

Also meine Frage ist das: Warum wurde nicht die XmlDocument (oder XDocument) dynamisch gemacht, oder warum gibt es nicht eine neue Klasse für dynamische XML-Manipulation in C# 4?

Dies ist noch fremd für mich, wenn ich bedenke, dass in Powershell, XmlDocumentdynamisch ist, Code wie $xmlDoc.root.subnode.subsubnode es funktioniert.

+5

Wenn irgendein Typ geändert würde, wäre es XDocument, nicht XmlDocument. –

+0

Ist die Antwort auf diese Frage auch speziell für C#? –

+2

AFAIK, 'dynamic' ist eine Eigenschaft von C#, also ja, spezifisch für C#. – svick

Antwort

6

Gegeben einige der Kommentare, lassen Sie mich eine alternative Antwort geben. Die ursprüngliche Frage fragte, warum XmlDocument in .NET 4 nicht dynamisch war. Obwohl es möglich ist, den vorhandenen XML-Dokumentklassen über IDynamicMetaObjectProvider die Eigenschaft "expando" hinzuzufügen, ist dies wahrscheinlich ein nicht-triviales Unterfangen. Um das ursprüngliche Xml-Objektmodell aus System.Xml vollständig dynamisch zu machen, müssten einige umfangreiche Änderungen am Xml-Framework vorgenommen werden. Dazu müsste IDynamicMetaObjectProvider jedem beteiligten Objekt hinzugefügt werden. Dazu gehören XmlDocument, XmlElement, XmlAttribute, XmlNode und alle anderen XML-Inhaltstypen wie Kommentare, Textknoten usw. Darüber hinaus gibt es eine beträchtliche Menge an unterstützender Infrastruktur, internen Typen usw., die an der Suche und Verarbeitung von XML beteiligt sind Elemente, Attribute und Werte müssten ebenfalls geändert werden (öffnen Sie Reflector und werfen Sie einen Blick auf System.Xml ... mehr als die Hälfte der Typen sind interne und sie sind alle stark voneinander abhängig und die verfügbaren öffentlichen Typen .)

Es ist auch wichtig, den richtigen Umfang der Implementierung von Expando-Eigenschaften für Xml in .NET zu berücksichtigen. Würden Sie nur bei XmlDocument und verwandten Typen anhalten? Oder wäre es besser, XPath, Xml Schema usw. einzubeziehen?

Um die ursprüngliche Frage zu beantworten, "Warum XmlDocument in .NET 4 dynamisch ist?", Denke ich, die einfache Antwort lautet: Implementieren vollständig 'dynamische' APIs, oder im Fall von Xml hier, APIs, die bieten Eigenschaftsexpansion von beliebigen XML-Dokumenten ist bei weitem keine triviale Aufgabe. Angesichts der Arbeitsethik von Microsoft ist es logisch, dass sie sich einer solchen Aufgabe nicht leichtfertig nähern würden, und wenn sie versuchen, Expando-Eigenschaften für das Xml-Framework zu implementieren, würde ich hoffen und erwarten, dass es mit der gleichen Sorgfalt und Sorgfalt durchgeführt wird Sie geben dem Rest von .NET.

+1

Interessante Antwort, aber meine Frage ist, warum gibt es keinen Typ, der die 'xmlDoc.root_nodeSubnode' Syntax in C# verarbeiten könnte? (Wahrscheinlich durch die Implementierung von 'IDynamicMetaObjectProvider', wenn ich es richtig verstehe.) – svick

+0

Aber Sie können das in C# 4 tun, können Sie die Mitglieder-Suche selbst verwalten, siehe z. http://channel9.msdn.com/posts/RobBagby/deCast-Dynamic-Xml-with-C-40/. – svick

+0

Ja, Objekte können wirklich dynamisch sein. Siehe "DynamicObject" - und "ExpandoObject" -Klassen auf MSDN und die von ihnen implementierten Schnittstellen. Als solche ist die Antwort effektiv falsch, und es ist durchaus möglich, z.B. 'XmlDocument', um in zukünftigen Versionen die Fähigkeit hinzuzufügen, auf die als' ((dynamic) root) .foo.bar.baz' zugegriffen werden kann. –

-1

Wahrscheinlich haben sie nicht darüber nachgedacht, und Programmierer sind in der Regel nicht auslöserfreudig, wenn es um Dynamik geht: Dynamik ist eine Zeitbombe. Fangen Sie so viel wie möglich zur Kompilierzeit ab ...

+1

Die Sache ist, Sie wissen nie, welche XML erhalten Sie und ob es sein wird, was Sie erwarten. Und wenn nicht, musst du das zur Laufzeit handhaben, egal ob du Dynymics verwendest oder nicht. – svick

+0

@svick: Dafür ist die Schema-Validierung zuständig. –

-2

Da XmlDocument älter ist als Generics und das Reparieren würde es alten Code zerstören.

Auch XmlDocument ist als halb veraltet aufgeführt.

+3

Wie würde es bestehenden Code brechen, wenn eine Klasse eine neue Schnittstelle unterstützt, die nicht vorhanden war, als der Code geschrieben wurde? – Niki

12

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.

+1

"Es adressiert GENAU, wofür das dynamische Schlüsselwort bestimmt war" - was das 'dynamische' Schlüsselwort _beabsichtigt_ war, ist nur etwas für die Entwickler der Sprache und die damit verbundenen Teil der Laufzeitbibliothek, kann autorisierend beantworten. In diesem Fall wurde wiederholt festgestellt, dass der Anwendungsfall # 1 für 'dynamic' tatsächlich mit Office-APIs arbeitet und # 2 mit Objekten arbeitet, die aus dynamischen Sprachen verfügbar sind. Das soll nicht heißen, dass es keine anderen gültigen Verwendungen gibt, aber ich denke, dass die Behauptung "beabsichtigt für" etwas zu durchsetzungsfähig ist. –

+1

Fair genug. Ich denke, ich hätte sagen sollen: "Es adressiert, was die DynamicObject-Klasse in Verbindung mit dem dynamischen Schlüsselwort MOST WAHRSCHEINLICH bestimmt war". Sogar die Blogger bei Microsoft verwenden es für diesen Zweck: http://blogs.msdn.com/b/csharpfaq/archive/2009/10/19/dynamic-in-c-4-0-creating- wrappers-with-dynamicobject.aspx – mattmc3

Verwandte Themen