2010-06-23 10 views
10

Una de las áreas donde me gustaría ver el uso de dynamic es XML. Creo que simplificaría la escritura del código de procesamiento XML y creo que vi algunos ejemplos antes de que salga C# 4 y se menciona in this answer como uno de los usos de esta función.¿Por qué XmlDocument no es dinámico en .NET 4?

Entonces, mi pregunta es esta: ¿por qué no se hizo el XmlDocument (o XDocument) dinámico, o por qué no hay alguna clase nueva para la manipulación dinámica de XML en C# 4?

Esto es aún más extraño para mí, cuando considero que en PowerShell, XmlDocument es dinámico, un código como $xmlDoc.root.subnode.subsubnode trabaja allí.

+5

Si se cambiara cualquier tipo, sería XDocument, no XmlDocument. –

+0

Además, ¿la respuesta a esta pregunta es específica para C#? –

+2

AFAIK, 'dynamic' es una característica de C#, así que sí, específica para C#. – svick

Respuesta

6

Dado algunos de los comentarios, déjenme proporcionar una respuesta alternativa. La pregunta original preguntaba por qué XmlDocument no era dinámico en .NET 4. Si bien es posible agregar la capacidad de propiedad "expando" a las clases de documento xml existentes a través del IDynamicMetaObjectProvider, hacerlo probablemente no sea una tarea trivial. Hacer que el modelo original de objetos Xml de System.Xml sea completamente dinámico requeriría algunas modificaciones extensas del marco Xml, y requeriría que IDynamicMetaObjectProvider se agregue a cada objeto involucrado. Eso incluye XmlDocument, XmlElement, XmlAttribute, XmlNode y todos los otros tipos de contenido xml, como comentarios, nodos de texto, etc. Además, una cantidad considerable de infraestructura de soporte, tipos internos, etc. que están involucrados en la búsqueda y el procesamiento de los elementos y atributos y valores también deberían modificarse (abrir Reflector y echar un vistazo a System.Xml ... más de la mitad de los tipos son internos, y todos son altamente interdependientes entre sí y con los tipos públicos disponibles) .)

También es importante considerar el alcance adecuado de la implementación de las propiedades de expansión de Xml en .NET. ¿Se detendría solo en XmlDocument y tipos relacionados? ¿O sería más apropiado incluir XPath, Xml Schema, etc.?

Para responder a la pregunta original "¿Por qué XmlDocument no es dinámico en .NET 4?", Creo que la respuesta simple es: Implementar API completamente "dinámicas", o en el caso de Xml aquí, API que proporcionan la expansión de propiedades de documentos xml arbitrarios, está lejos de ser una tarea trivial. Dada la ética de trabajo de Microsoft, tiene sentido lógico que no aborden esa tarea a la ligera, y si intentan implementar propiedades de expansión para el marco Xml, espero y espero que se haga con el mismo nivel de atención y cuidado cuidadosos. dan al resto de .NET.

+1

Interesante respuesta, pero mi pregunta es, ¿por qué no hay ningún tipo que pueda manejar la sintaxis 'xmlDoc.root.subnode.subsubnode' en C#? (Probablemente implementando 'IDynamicMetaObjectProvider', si lo entiendo correctamente.) – svick

+0

Pero puede hacerlo en C# 4, puede administrar la búsqueda de miembros usted mismo, vea p. http://channel9.msdn.com/posts/RobBagby/deCast-Dynamic-Xml-with-C-40/. – svick

+0

Sí, los objetos pueden ser realmente dinámicos. Consulte las clases 'DynamicObject' y' ExpandoObject' en MSDN, y las interfaces que implementan. Como tal, la respuesta es efectivamente incorrecta, y es bastante posible, por ej. 'XmlDocument' para agregar la capacidad de ser accedido como' ((dynamic) root) .foo.bar.baz' en versiones futuras. –

-1

Lo más probable es que no lo hayan pensado, y los programadores, por lo general, no se sienten cómodos con las dinámicas de colocación en todas partes: la dinámica es una bomba de tiempo. Capture todo lo que pueda en tiempo de compilación ...

+1

El hecho es que nunca sabes qué XML obtendrás y si será lo que esperas. Y si no es así, debes manejar eso en tiempo de ejecución, ya sea que uses dynymics o no. – svick

+0

@svick: para eso es la validación de esquema. –

-2

Porque XmlDocument es anterior a la genéreica y repararlo podría romper el código anterior.

Además, XmlDocument aparece como semi-obsoleto.

+3

¿Cómo rompería el código existente si una clase admite una nueva interfaz que no estaba allí cuando se escribió el código? – Niki

12

Me sorprende la cantidad de discusiones aparentemente autoritarias sin respuesta. Tu pregunta es FANTÁSTICA. Se dirige EXACTAMENTE al tipo de cosas increíbles a las que se destinó la palabra clave dynamic. El problema es que no mucha gente sabe cómo usarlo al máximo.

Si bien MS no construyó los objetos XML dinámicos para nosotros, nos dieron las herramientas para hacerlo nosotros mismos con la clase DynamicObject. Esta es una forma de hacer lo que está pidiendo con la antigua clase 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; 
    } 
} 

Y así es como llamarías al código.Tenga en cuenta que esto compila en C# 4.0 solamente.

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); 
     } 
    } 
} 

No me puedo atribuir todo el mérito. Bamboo wrote this code para Boo en 2003. C# ha estado recibiendo lentamente las características que Boo ha tenido en .NET durante años ... primer tipo de inferencia, y ahora el estilo IQuackFu DynamicObject. Una vez que implementen macros de lenguaje para poder crear DSL, creo que se habrán puesto al día.

Dejaré de escribir al lector la versión XElement de este código más nueva.

+1

"Trata EXACTAMENTE para qué se concibió la palabra clave dinámica" - para qué se concibió la palabra clave 'dynamic' es algo solo para los diseñadores del lenguaje, y los relacionados parte de la biblioteca de tiempo de ejecución, puede responder con autoridad. En este caso, se afirmó repetidamente que el caso de uso n. ° 1 para 'dynamic' está de hecho trabajando con las API de Office, y el n. ° 2 está trabajando con objetos expuestos de lenguajes dinámicos. Esto no quiere decir que no haya otros usos válidos, pero a mí me parece que el reclamo de "pretendida" es demasiado asertivo. –

+1

Bastante justo. Supongo que debería haber dicho "Se trata de lo que la clase DynamicObject junto con la palabra clave dinámica era MÁS PROBABLE". Incluso los bloggers de Microsoft lo están usando para este propósito: http://blogs.msdn.com/b/csharpfaq/archive/2009/10/19/dynamic-inc-c-4-0-creating- wrappers-with-dynamicobject.aspx – mattmc3

Cuestiones relacionadas