Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
XName y XNamespace los objetos se atomizan; es decir, si contienen el mismo nombre completo, hacen referencia al mismo objeto. Esto produce ventajas de rendimiento para las consultas: al comparar dos nombres atomizados por igualdad, el lenguaje intermedio subyacente solo tiene que determinar si las dos referencias apuntan al mismo objeto. El código subyacente no tiene que realizar comparaciones de cadenas, lo que tardaría más tiempo.
Semántica de atomización
La atomización significa que si dos XName objetos tienen el mismo nombre local y están en el mismo espacio de nombres, comparten la misma instancia. De la misma manera, si dos XNamespace objetos tienen el mismo URI de espacio de nombres, comparten la misma instancia.
Para que una clase habilite objetos atomizados, el constructor de la clase debe ser privado, no público. Esto se debe a que si el constructor fuera público, podría crear un objeto no atomizado. Las clases XName y XNamespace implementan un operador de conversión implícito para convertir una cadena en un XName o XNamespace. Así es como se obtiene una instancia de estos objetos. No se puede obtener una instancia mediante un constructor, ya que el constructor no es accesible.
XName e XNamespace implementa también los operadores de igualdad y desigualdad, que determinan si los dos objetos que se comparan son referencias a la misma instancia.
Ejemplo: Crear objetos y mostrar que los nombres idénticos comparten una instancia
El código siguiente crea algunos XElement objetos y muestra que los nombres idénticos comparten la misma instancia.
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
En este ejemplo se genera la siguiente salida:
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 se mencionó anteriormente, la ventaja de los objetos atomizados es que cuando se usa uno de los métodos del eje que toman como XName parámetro, el método del eje solo tiene que determinar que dos nombres hacen referencia a la misma instancia para seleccionar los elementos deseados.
El siguiente ejemplo pasa XName a la llamada del método Descendants, cuyo rendimiento mejora gracias al patrón de atomización.
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
En este ejemplo se genera la siguiente salida:
<C1>1</C1>
<C1>1</C1>