Compartilhar via


XName atomizado e XNamespace objeto (LINQ to XML)

Os objetos XName e XNamespace são atomizados, isto é, se eles contêm o mesmo nome qualificado, referem-se ao mesmo objeto. Este benefícios de desempenho das para consultas: quando você compara dois nomes atomizados para igualdade, o linguagem intermediária subjacente só precisa determinar se o ponto de duas referências para o mesmo objeto. O código subjacente não precisa fazer as comparações de cadeia de caracteres, que levariam mais tempo.

Semântica de atomização

A atomização significa que se dois objetos de XName têm o mesmo nome local, e estão no mesmo namespace, compartilham a mesma instância. Da mesma forma, se dois objetos de XNamespace têm o mesmo URI de namespace, compartilham a mesma instância.

Para que uma classe permite objetos atomizados, o construtor para a classe deve ser particular, não público. Isso ocorre porque se foi o construtor público, você pode criar um objeto não atomizado. As classes de XName e de XNamespace implementam um operador de conversão implícita para converter uma cadeia de caracteres em XName ou em XNamespace. Isso é como você obtém uma instância desses objetos. Você não pode obter uma instância usando um construtor, porque o construtor é inacessível.

XName e XNamespace também implementam os operadores de igualdade e desigualdade, que determinam se dois objetos que estão sendo comparados são referências para a mesma instância.

Exemplo: criar objetos e mostrar que nomes idênticos compartilham uma instância

O código a seguir cria alguns objetos de XElement e demonstrar-los que os nomes idênticos compartilham a mesma instância.

var 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");
Dim r1 As New XElement("Root", "data1")
Dim r2 As XElement = XElement.Parse("<Root>data2</Root>")

If DirectCast(r1.Name, Object) = DirectCast(r2.Name, Object) Then
    Console.WriteLine("r1 and r2 have names that refer to the same instance.")
Else
    Console.WriteLine("Different")
End If

Dim n As XName = "Root"

If DirectCast(n, Object) = DirectCast(r1.Name, Object) Then
    Console.WriteLine("The name of r1 and the name in 'n' refer to the same instance.")
Else
    Console.WriteLine("Different")
End If

Esse exemplo gera a saída a seguir:

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.

Como mencionado anteriormente, a vantagem de objetos atomizados é que quando você usa um dos métodos do eixo que recebem XName como um parâmetro, o método do eixo só precisa determinar que dois nomes referenciam a mesma instância para selecionar os elementos desejados.

O exemplo a seguir XName passa a chamada de método Descendants , que tem em melhor desempenho devido ao padrão de atomização.

var 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);
Dim root As New XElement("Root", New XElement("C1", 1), New XElement("Z1", New XElement("C1", 2), New XElement("C1", 1)))

Dim query = From e In root.Descendants("C1") Where CInt(e) = 1

For Each z In query
    Console.WriteLine(z)
Next

Esse exemplo gera a saída a seguir:

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