読者です 読者をやめる 読者になる 読者になる

いろいろ備忘録日記

主に .NET と Python絡みのメモを公開しています。

Linq入門記-61 (LINQ to XML, 要素のクローンとアタッチ)


LINQ to XMLにて新たにツリーに追加された要素の特徴 (クローンとアタッチ) について.

過去の内容は以下から見れます。よろしければご参照くださいませ。


LINQ to XMLでは、新たに要素を作成した際に
その要素に予め親要素が存在するか否かによって
別のXMLツリー内に要素追加した時の状態が変わります。

  • 親要素が存在しない場合
    • アタッチされる. (つまりコピーされずに元の参照のまま)
  • 親要素が存在する場合
    • クローンされる. (つまりコピーされる)


アタッチした場合、同じ参照を持っていることになるので
当然、元の値を変更した場合、別のXMLツリーに追加した方も変更されます。
クローンされている場合は、コピーされているので、別のXMLツリーに追加した方は変更ありません。


以下、サンプルです。

#region LinqSamples-58
  /// <summary>
  /// LINQ to XMLのサンプルです.
  /// </summary>
  /// <remarks>
  /// 要素のクローンとアタッチについてのサンプルです.
  /// </remarks>
  public class LinqSamples58 : IExecutable
  {
    public void Execute()
    {
      //
      // 親要素を持たない要素を作成し、特定のXMLツリーの中に組み込む. (アタッチ)
      //
      var noParent = new XElement("NoParent", true);
      var tree1    = new XElement("Parent", noParent);
      
      var noParent2 = tree1.Element("NoParent");
      Console.WriteLine("参照が同じ? = {0}", noParent == noParent2);
      Console.WriteLine(tree1);
      
      // 値を変更して確認.
      noParent.SetValue(false);
      Console.WriteLine(noParent.Value);
      Console.WriteLine(tree1.Element("NoParent").Value);
      
      Console.WriteLine("==========================================");
      
      //
      // 親要素を持つ要素を作成し、特定のXMLツリーの中に組み込む. (クローン)
      //
      var origTree = new XElement("Parent", new XElement("WithParent", true));
      var tree2    = new XElement("Parent", origTree.Element("WithParent"));
      
      Console.WriteLine("参照が同じ? = {0}", origTree.Element("WithParent") == tree2.Element("WithParent"));
      Console.WriteLine(tree2);
      
      // 値を変更して確認
      origTree.Element("WithParent").SetValue(false);
      Console.WriteLine(origTree.Element("WithParent").Value);
      Console.WriteLine(tree2.Element("WithParent").Value);
    }
  }
  #endregion


実行結果は以下のようになります。

  参照が同じ? = True
  
    true
  
  false
  false
  ==========================================
  参照が同じ? = False
  
    true
  
  false
  true

以下、参照リソースです。

================================
過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。