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

XName- und XNamespace-Objekte werden 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- und XNamespace-Klassen implementieren einen impliziten Konvertierungsoperator zum Konvertieren einer Zeichenfolge in eine XName oder XNamespace. 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 erzeugt die folgende 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 der Achsenmethoden, die als Parameter einen XName erfordern, zum Auswählen der gewünschten Elemente nur ermittelt werden muss, ob die beiden Namen auf dieselbe Instanz verweisen.

Das folgende Beispiel übergibt eine XName an den Descendants-Methodenaufruf, der aufgrund des Atomarisierungsmusters eine bessere Leistung aufweist.

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 erzeugt die folgende Ausgabe:

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

Siehe auch

Leistung (LINQ to XML) (C#)