XName 和 XNamespace 对象 被原子化;也就是说,如果它们包含相同的限定名称,则它们引用同一对象。 这会产生查询的性能优势:比较两个原子化名称是否相等时,基础中间语言只需确定两个引用是否指向同一对象。 基础代码不必执行字符串比较,这需要更长的时间。
原子化语义
原子化意味着,如果两个 XName 对象具有相同的本地名称,并且它们位于同一命名空间中,则它们共享同一实例。 同样,如果两个 XNamespace 对象具有相同的命名空间 URI,则它们共享相同的实例。
要使类启用原子化对象,该类的构造函数必须是私有的,而不是公共的。 这是因为如果构造函数是公共的,则可以创建非原子化对象。 XName和XNamespace类实现隐式转换运算符,以将字符串转换为XName或 XNamespace。 这就是获取这些对象的实例的方式。 无法使用构造函数获取实例,因为构造函数不可访问。
XName 并 XNamespace 实现相等运算符和不相等运算符,该运算符确定要比较的两个对象是否引用同一实例。
示例:创建对象并证明相同的名称共享一个实例
以下代码将创建一些 XElement 对象,并演示相同的名称共享同一实例。
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
此示例生成以下输出:
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.
如前所述,原子化对象的优势在于,当你使用以XName作为参数的轴方法之一时,轴方法只需判断两个名称是否引用同一实例来选择所需的元素。
以下示例将一个 XName 传递给 Descendants 方法调用,该方法随后由于原子化模式而具有更好的性能。
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
此示例生成以下输出:
<C1>1</C1>
<C1>1</C1>