2010-04-13 4 views
3

Может кто-нибудь объяснить, почему изменился исходный адрес узла улицы XElement? Похоже, что клиент1 имеет ссылку на адрес XElement, но клиент2 и клиент3 сделали копии.LINQ to XML Cloning

Почему первоначальный адрес изменился? (Пример 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(); 

ВЫВОД

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> 

ответ

1

Тот же XElement не может быть в нескольких деревьях. Конечно, вы можете иметь несколько ссылок на один и тот же XElement в определенном дереве, но тот же XElement не может быть в нескольких деревьях.

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

8

От вопроса:

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

Да, это именно то, что происходит. Из docs for XElement contents:

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

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