Share via


Atomized XName and XNamespace Objects (LINQ to XML)

XName and XNamespace objects are atomized; that is, if they contain the same qualified name, they refer to the same object. This yields performance benefits for queries: When you compare two atomized names for equality, the underlying intermediate language only has to determine whether the two references point to the same object. The underlying code does not have to do string comparisons, which would be time consuming.

Atomization Semantics

Atomization means that if two XName objects have the same local name, and they are in the same namespace, they share the same instance. In the same way, if two XNamespace objects have the same namespace URI, they share the same instance.

For a class to enable atomized objects, the constructor for the class must be private, not public. This is because if the constructor were public, you could create a non-atomized object. The XName and XNamespace classes implement an implicit conversion operator to convert a string into an XName or XNamespace. This is how you get an instance of these objects. You cannot get an instance by using a constructor, because the constructor is inaccessible.

XName and XNamespace also implement the equality and inequality operators, to determine whether the two objects being compared are references to the same instance.

Example

The following code creates some XElement objects and demonstrates that identical names share the same instance.

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

This example produces the following output:

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.

As mentioned earlier, the benefit of atomized objects is that when you use one of the axis methods that take an XName as a parameter, the axis method only has to determine that two names reference the same instance to select the desired elements.

The following example passes an XName to the Descendants method call, which then has better performance because of the atomization pattern.

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

This example produces the following output:

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

See Also

Concepts

Performance (LINQ to XML)