Frage

Die aktuellen guidlelines für explizite Memberimplementierung empfehlen:

  • Verwenden von expliziten Mitgliedern private Schnittstelle Implementierungen zu nähern. Wenn Sie eine Schnittstelle für nur Infrastruktur Gründen implementieren müssen und Sie nie erwarten Entwickler Methoden direkt anrufen an dieser Schnittstelle von dieser Art dann die Mitglieder ausdrücklich zu ‚verstecken‘ setzen sie aus der Öffentlichkeit .
  • Expose eine alternative Art und Weise alle explizit implementiert Mitglieder zuzugreifen, die Unterklassen außer Kraft setzen dürfen.

Ein gutes Beispiel dafür ist, wenn Sie die IXmlSerializable Schnittstelle. Die ReadXml und WriteXml Methoden werden voraussichtlich durch die XmlSerializer aufgerufen werden und sind nicht in der Regel direkt von den Entwicklern genannt.

Wenn eine alternative Möglichkeit bereitstellt, um explizit Mitglieder zugreifen Sie mögen außer Kraft gesetzt werden, damit, so scheint es sinnvoll, die explizit umgesetzt Mitglied zu nennen, um Code-Duplizierung zu vermeiden. Betrachten Sie das folgende:

using System;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace Demo
{
    /// <summary>
    /// Demonstrates explicit implementation of the IXmlSerializable interface.
    /// </summary>
    [Serializable(), XmlRoot(ElementName = "foo")]
    public class Foo : IXmlSerializable
    {
        //============================================================
        //  IXmlSerializable Implementation
        //============================================================
        #region GetSchema()
        /// <summary>
        /// Returns an <see cref="XmlSchema"/> that describes the XML representation of the object.
        /// </summary>
        /// <returns>
        /// An <see cref="XmlSchema"/> that describes the XML representation of the object that is 
        /// produced by the <see cref="IXmlSerializable.WriteXml(XmlWriter)"/> method and consumed by the <see cref="IXmlSerializable.ReadXml(XmlReader)"/> method.
        /// </returns>
        /// <remarks>This method is reserved and should not be used.</remarks>
        XmlSchema IXmlSerializable.GetSchema()
        {
            return null;
        }
        #endregion

        #region ReadXml(XmlReader reader)
        /// <summary>
        /// Generates an object from its XML representation.
        /// </summary>
        /// <param name="reader">The <see cref="XmlReader"/> stream from which the object is deserialized.</param>
        /// <exception cref="ArgumentNullException">The <paramref name="reader"/> is a <b>null</b> reference (Nothing in Visual Basic).</exception>
        void IXmlSerializable.ReadXml(XmlReader reader)
        {
            // Class state values read from supplied XmlReader
        }
        #endregion

        #region WriteXml(XmlWriter writer)
        /// <summary>
        /// Converts an object into its XML representation.
        /// </summary>
        /// <param name="writer">The <see cref="XmlWriter"/> stream to which the object is serialized.</param>
        /// <exception cref="ArgumentNullException">The <paramref name="writer"/> is a <b>null</b> reference (Nothing in Visual Basic).</exception>
        void IXmlSerializable.WriteXml(XmlWriter writer)
        {
            // Current class state values written using supplied XmlWriter
        }
        #endregion

        //============================================================
        //  Public Methods
        //============================================================
        #region WriteTo(XmlWriter writer)
        /// <summary>
        /// Saves the current <see cref="Foo"/> to the specified <see cref="XmlWriter"/>.
        /// </summary>
        /// <param name="writer">The <see cref="XmlWriter"/> stream to which the <see cref="Foo"/> is serialized.</param>
        /// <exception cref="ArgumentNullException">The <paramref name="writer"/> is a <b>null</b> reference (Nothing in Visual Basic).</exception>
        public void WriteTo(XmlWriter writer)
        {
            writer.WriteStartElement("foo");

            ((IXmlSerializable)this).WriteXml(writer);

            writer.WriteEndElement();
        }
        #endregion
    }
}

Meine Frage ist in Bezug darauf, wie teuer die Boxen der WriteXml Methode ist in dieser Implementierung. Ist ((IXmlSerializable) this) .WriteXml (Drehbuch) werde die Leistung erheblich behindern?

War es hilfreich?

Lösung

Es gibt keine Boxen in Ihrem Beispiel nehmen ... es ist nur eine Besetzung, und es ist auflösbar bei der Kompilierung, so dass es überhaupt keine Auswirkungen auf die Leistung haben.

Edit:. mit ILDASM es sucht, wird die Schnittstelle Besetzung gibt Ihnen einen virtuellen Methodenaufruf im Vergleich zu einem normalen Methodenaufruf, aber das ist vernachlässigbar (es gibt noch keine Boxen beteiligt)

Bearbeiten. 2: Wenn Sie eine Struktur statt einer Klasse zu verwenden, dann erhalten Sie eine Box erhalten über die Schnittstelle gehen, mit viel mehr einer Leistungseinbuße

Andere Tipps

Nein, die Kosten für eine Reihe von Daten zu einem XmlWriter des Schreibens wird die Box-Kosten in den Schatten stellt.

Boxen bestehen aus:

  1. ein Stück Speicher aus dem GC Allokierung
  2. Initialisieren seinen Header mit den richtigen Typ Informationen
  3. Kopieren der Valuetype Daten in den Heap-Speicher

Als solches ist es ungefähr das gleiche wie ein Objekt Konstruktion. Wenn auch nur ein einziges Stück von Daten, die Sie den XmlWriter gerade schreiben nicht bereits ein String ist, werden Sie diese Kosten auf jeden Fall zahlen müssen, um die Zeichenfolge zu konstruieren schreiben zu können.

Warum nicht einfach haben sie beide eine private Methode aufrufen, die die Funktion der explizit implementierte Schnittstelle führt?

public void IXmlSerializable.WriteXml( XmlWriter writer )
{
    InternalWriteXml( writer );
}

public void WriteTo(XmlWriter writer)
{
    writer.WriteStartElement("foo");

    InternalWriteXml(writer);

    writer.WriteEndElement();
}

private void InternalWriteXml( XmlWriter writer )
{
    ...
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top