다음을 통해 공유


원자화된 XName 및 XNamespace 개체(LINQ to XML)

XNameXNamespace 개체는 원자화됩니다. 즉, 동일한 정규화된 이름을 가진 경우 동일한 개체를 참조합니다. 이렇게 하면 쿼리에 대한 성능 이점이 발생합니다. 두 개의 원자화된 이름을 같음으로 비교할 때 기본 중간 언어는 두 참조가 동일한 개체를 가리키는지 여부를 결정하기만 하면 됩니다. 기본 코드는 문자열 비교를 수행할 필요가 없으므로 시간이 더 오래 걸립니다.

원자화 의미 체계

원자화는 두 XName 개체의 로컬 이름이 같고 동일한 네임스페이스에 있는 경우 동일한 인스턴스를 공유한다는 것을 의미합니다. 동일한 방식으로 두 XNamespace 개체의 네임스페이스 URI가 같으면 동일한 인스턴스를 공유합니다.

원자화된 개체를 사용하도록 설정하는 클래스의 경우 클래스의 생성자는 public이 아닌 private이어야 합니다. 생성자가 public이면 원자화되지 않은 개체를 만들 수 있기 때문입니다. XNameXNamespace 클래스는 문자열을 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을 매개변수로 사용하는 축 메서드 중 하나를 사용할 때, 축 메서드가 두 이름이 동일한 인스턴스를 참조하고 있는지만 확인하면 원하는 요소를 선택할 수 있다는 것입니다.

다음 예제에서는 XNameDescendants 메서드 호출에 전달하여 원자화 패턴 덕분에 성능이 향상됩니다.

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>