共用方式為


原子化 XName 和 XNamespace 物件(LINQ to XML)

XNameXNamespace 物件會 原子化;也就是說,如果它們包含相同的限定名稱,則會參考相同的物件。 這會產生查詢的效能優點:當您比較兩個原子化名稱是否相等時,基礎中繼語言只需要判斷兩個參考是否指向相同的物件。 基礎程序代碼不需要執行字串比較,這需要較長的時間。

原子化語意

Atomization 表示如果兩個 XName 物件具有相同的本機名稱,而且它們位於相同的命名空間中,則會共用相同的實例。 同樣地,如果兩個 XNamespace 物件具有相同的命名空間 URI,它們就會共用相同的實例。

若要讓類別啟用原子化對象,類別的建構函式必須是私用的,而不是公用的。 這是因為如果建構函式是公用的,您可以建立非原子化物件。 XName類別 XNamespace 會實作隱含轉換運算元,將字串轉換成 XNameXNamespace。 這是您取得這些對象的實例的方式。 您無法使用建構函式取得實例,因為無法存取建構函式。

XNameXNamespace 也會實作相等和不相等運算符,以判斷要比較的兩個物件是否為相同實例的參考。

範例:建立物件並顯示相同的名稱共享實例

下列程式代碼建立一些 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>