LINQ to XML Cloning - PullRequest
       17

LINQ to XML Cloning

3 голосов
/ 13 апреля 2010

Может кто-нибудь объяснить, почему меняется первоначальный адрес уличного узла XElement? Похоже, что customer1 содержит ссылку на адрес XElement, но customer2 и customer3 получили копии.

Почему изменился оригинальный адрес? (Пример LINQPad)

var address =
    new XElement ("address",
        new XElement ("street", "Lawley St"), 
        new XElement ("town", "North Beach")
    );

var customer1 = new XElement ("customer1", address);
var customer2 = new XElement ("customer2", address);
var customer3 = new XElement ("customer3", address);

customer1.Element ("address").Element ("street").Value = "Another St";

Console.WriteLine (customer2.Element ("address").Element ("street").Value);
Console.WriteLine ();

address.Dump();
Console.WriteLine ();

customer1.Dump();
Console.WriteLine ();

customer2.Dump();
Console.WriteLine ();

customer3.Dump();

OUTPUT

Lawley St


<address>
  <street>Another St</street>
  <town>North Beach</town>
</address> 


<customer1>
  <address>
    <street>Another St</street>
    <town>North Beach</town>
  </address>
</customer1> 


<customer2>
  <address>
    <street>Lawley St</street>
    <town>North Beach</town>
  </address>
</customer2> 


<customer3>
  <address>
    <street>Lawley St</street>
    <town>North Beach</town>
  </address>
</customer3> 

Ответы [ 2 ]

8 голосов
/ 13 апреля 2010

Из вопроса:

Похоже, клиент1 держит ссылка на адрес XElement но customer2 и customer3 приняли копии.

Да, именно так и происходит. Из документов для содержимого XElement :

При добавлении XNode или XAttribute объекты, если новый контент не имеет родитель, то объекты просто привязан к дереву XML. Если новый контент уже является родителем и является часть другого XML-дерева, затем новый контент клонируется, а новый клонированный контент прикреплен к XML дерево.

В первом случае address не имеет родителя, поэтому он подключен напрямую. После этого у есть родитель, поэтому он сначала клонируется.

1 голос
/ 13 апреля 2010

Один и тот же XElement не может быть в нескольких деревьях. Конечно, вы можете иметь несколько ссылок на один и тот же XElement в определенном дереве, но один и тот же XElement не может быть в нескольких деревьях К customer1, вы действительно и действительно добавили этот address XElement. К тому времени, когда вы «добавили» его к customer2, фактический address1 XElement действительно не мог быть добавлен, потому что это уже узел в другом XElement. Поскольку он не может добавить исходный address в качестве узла, конструктор XElement помещает клон этого XElement в customer2 и customer3. Теперь у вас есть три эквивалентных «адресных» XElements.

...