Sdílet prostřednictvím


Atomisierte XName- und XNamespace-Objekte (LINQ to XML)

Aktualisiert: November 2007

Die XName-Objekte und XNamespace-Objekte sind atomisiert. Dies bedeutet, dass sie auf dasselbe Objekt verweisen, wenn sie denselben qualifizierten Namen enthalten. Dadurch wird die Leistung von Abfragen verbessert: Beim Vergleichen zweier atomisierter Namen auf Übereinstimmung muss die zugrunde liegende Intermediate Language nur ermitteln, ob die beiden Verweise auf dasselbe Objekt zeigen. Im zugrunde liegenden Code müssen keine zeitaufwändigen Zeichenfolgenvergleiche ausgeführt werden.

Atomisierungssemantik

Atomisierung bedeutet, dass zwei XName-Objekte dieselbe Instanz gemeinsam nutzen, wenn sie über denselben lokalen Namen verfügen und sich im selben Namespace befinden. Dementsprechend nutzen zwei XNamespace-Objekte dieselbe Instanz gemeinsam, wenn sie über denselben Namespace-URI verfügen.

Damit eine Klasse atomisierte Objekte unterstützt, muss der Konstruktor für die Klasse privat sein, nicht öffentlich. Bei einem öffentlichen Konstruktor könnten Sie ein nicht atomisiertes Objekt erstellen. Die XName-Klasse und die XNamespace-Klasse implementieren einen impliziten Konvertierungsoperator, um eine Zeichenfolge in einen XName oder einen XNamespace zu konvertieren. Auf diese Weise können Sie eine Instanz dieser Objekte abrufen. Sie können keine Instanz über einen Konstruktor abrufen, da Sie auf den Konstruktor nicht zugreifen können.

Außerdem werden von XName und XNamespace Gleichheits- und Ungleichheitsoperatoren implementiert, mit denen Sie ermitteln können, ob die beiden verglichenen Objekte Verweise auf dieselbe Instanz darstellen.

Beispiel

Im folgenden Code werden mehrere XElement-Objekte erstellt, und es wird veranschaulicht, dass identische Namen dieselbe Instanz aufweisen.

XElement r1 = new XElement("Root", "data1");
XElement r2 = XElement.Parse("<Root>data2</Root>");

if ((object)r1.Name == (object)r2.Name)
    Console.WriteLine("r1 and r2 have names that refer to the same instance.");
else
    Console.WriteLine("Different");

XName n = "Root";

if ((object)n == (object)r1.Name)
    Console.WriteLine("The name of r1 and the name in 'n' refer to the same instance.");
else
    Console.WriteLine("Different");

Dieses Beispiel führt zur folgenden Ausgabe:

r1 and r2 have names that refer to the same instance.
The name of r1 and the name in 'n' refer to the same instance.

Wie bereits erwähnt, besteht der Vorteil atomisierter Objekte darin, dass beim Verwenden einer Achsenmethoden, die als Parameter einen XName entgegennimmt, zum Auswählen der gewünschten Elemente nur ermittelt werden muss, ob die beiden Namen auf dieselbe Instanz verweisen.

Im folgenden Beispiel wird ein XName an den Descendants-Methodenaufruf übergeben. Dieser erreicht aufgrund des Atomarisierungsmusters eine bessere Leistung.

XElement root = new XElement("Root",
    new XElement("C1", 1),
    new XElement("Z1",
        new XElement("C1", 2),
        new XElement("C1", 1)
    )
);

var query = from e in root.Descendants("C1")
            where (int)e == 1
            select e;

foreach (var z in query)
    Console.WriteLine(z);

Dieses Beispiel führt zur folgenden Ausgabe:

<C1>1</C1>
<C1>1</C1>

Siehe auch

Konzepte

Leistung (LINQ to XML)