locked
The XElement class explicitly implements the IXmlISerializable interface? RRS feed

  • Question

  • I see a sentence on a training book.

    "The XElement class explicitly implements the IXmlSerializable interface, which contains the GetSchema, ReadXml, and WriteXml methods so this object can be serialized."

    I don't understand it. From the example, explicitly implements the IXmlSerializable interface is from a custom class rather than XElement class. Is MSDN wrong?


    • Edited by ardmore Monday, March 23, 2015 8:01 PM add link
    Monday, March 23, 2015 7:39 PM

Answers

  • >>My question is since ReadXml or WriteXml are methods inside XElement class, can we call them like?

    Since the methods are explicitly implemented you must cast the XElement to an IXmlSerializable before you can access the them:

    XElement sitemap = XElement.Load("http://www.dotnetperls.com/sitemap.xml");
    (sitemap as System.Xml.Serialization.IXmlSerializable).ReadXml(...);

    Explicit Interface Implementation (C# Programming Guide): https://msdn.microsoft.com/en-us/library/ms173157.aspx

    Please remember to mark helpful posts as answer to close your threads and then start a new thread if you have a new question.

    • Marked as answer by ardmore Monday, March 23, 2015 10:26 PM
    Monday, March 23, 2015 9:55 PM

All replies

  • I don't understand what the Stackoverflow example has to do with your question. XElement is a class that implements IXmlSerializable, it's as simple as that.
    Monday, March 23, 2015 8:05 PM
  • I mean in the stackoverflow example,the class is a customized one "MyCalendar:IXmlSerializable"

    public class MyCalendar : IXmlSerializable
    {
        private string _name;
        private bool _enabled;
        private Color _color;
        private List<MyEvent> _events = new List<MyEvent>();
    
    
        public XmlSchema GetSchema() { return null; }
    
        public void ReadXml(XmlReader reader)
        {

    If XElement is a class that implements IXmlSerializable, what is the detail then?

    public class XElement : IXmlSerializable
    {
        public XmlSchema GetSchema() { *detail*?; }
        public void ReadXml(XmlReader reader){*detail*?}

    Any source code of XElement class?

    Monday, March 23, 2015 8:37 PM
  • So you want to see how XElement implements IXmlSerializable?

    Sure, look here: http://referencesource.microsoft.com/#System.Xml.Linq/System/Xml/Linq/XLinq.cs,4938

    Monday, March 23, 2015 8:44 PM
  • True, I found it.

    public class XElement : XContainer, IXmlSerializable
    {
            XmlSchema IXmlSerializable.GetSchema() {
                return null;
            }
     
            
            void IXmlSerializable.ReadXml(XmlReader reader) {
                if (reader == null) throw new ArgumentNullException("reader");
                if (parent != null || annotations != null || content != null || lastAttr != null) throw new InvalidOperationException(Res.GetString(Res.InvalidOperation_DeserializeInstance));
                if (reader.MoveToContent() != XmlNodeType.Element) throw new InvalidOperationException(Res.GetString(Res.InvalidOperation_ExpectedNodeType, XmlNodeType.Element, reader.NodeType));
                ReadElementFrom(reader, LoadOptions.None);
            }
     
            void IXmlSerializable.WriteXml(XmlWriter writer) {
                WriteTo(writer);
            }

    My question is since ReadXml or WriteXml are methods inside XElement class, can we call them like?

    XElement sitemap = XElement.Load("http://www.dotnetperls.com/sitemap.xml");
    sitemap.ReadXml(blah..)


    Monday, March 23, 2015 9:07 PM
  • >>My question is since ReadXml or WriteXml are methods inside XElement class, can we call them like?

    Since the methods are explicitly implemented you must cast the XElement to an IXmlSerializable before you can access the them:

    XElement sitemap = XElement.Load("http://www.dotnetperls.com/sitemap.xml");
    (sitemap as System.Xml.Serialization.IXmlSerializable).ReadXml(...);

    Explicit Interface Implementation (C# Programming Guide): https://msdn.microsoft.com/en-us/library/ms173157.aspx

    Please remember to mark helpful posts as answer to close your threads and then start a new thread if you have a new question.

    • Marked as answer by ardmore Monday, March 23, 2015 10:26 PM
    Monday, March 23, 2015 9:55 PM
  • Leaving aside the issue of explicit interface implementation I don't think you can call those method the way you show in your example. At least ReadXml will fail due to the fact that the element content is unlikely to be null, if you look at the code you'll see that this leads to an InvalidOperationException.

    These methods aren't intended to be used directly, they're supposed to be called by the XML serialization code. That's why the interface is explicitly implemented in the first place.

    It's not clear why would you want this anyway, you have XElement.ReadFrom and XElement.Load if you want to load an XElement from an existing XmlReader.

    Monday, March 23, 2015 10:18 PM
  • Instead of the "as" operator

    (sitemap as System.Xml.Serialization.IXmlSerializable).ReadXml(...);

    I would use an implicit conversion to a separate variable, or a cast:

    ((System.Xml.Serialization.IXmlSerializable)sitemap).ReadXml(...);

    If there is a bug and sitemap does not implement the requested interface, then the "as" operator returns null, which would cause a NullReferenceException when trying to call ReadXml. With a cast, you instead get an InvalidCastException that shows the type of the object and the type of the interface, making it easier to understand what went wrong.

    Tuesday, March 24, 2015 9:26 AM