Home All Groups Group Topic Archive Search About

Why this code does not cause error in .NET 2 & 3.5 (bug?)

Author
29 Nov 2007 5:45 PM
Andrus
While iterating a collection it is not allowed to remove its element.
However code below runs *without* (!) error in .NET 2.0 and 3.5

There could be some buggy IEnumerable implementation that fails to report
errorneous
removal of collection content

Please confirm, is this .NET bug ?

Andrus.


using System;
using System.Windows.Forms;
using System.Xml;

public class Test
{
    [STAThread]
    static void Main()
    {
        try
        {
            XmlDocument xDoc = new XmlDocument();
            xDoc.PreserveWhitespace = false;
            xDoc.LoadXml(xml);
            XmlNodeList list = xDoc.SelectNodes("//comment()");
            foreach (XmlNode node in list)
            {
                node.ParentNode.RemoveChild(node);
            }
        }
        catch (Exception ex)
        {
            Clipboard.SetText(ex.ToString());
            MessageBox.Show(ex.ToString());
        }
    }

    const string xml = @"<?xml version=""1.0"">
<Report><!-- --></Report>
    ";

}

Author
29 Nov 2007 6:20 PM
Chris Shepherd
Andrus wrote:
> While iterating a collection it is not allowed to remove its element.
> However code below runs *without* (!) error in .NET 2.0 and 3.5
>
> There could be some buggy IEnumerable implementation that fails to report
> errorneous
> removal of collection content
>
> Please confirm, is this .NET bug ?

No, it isn't because "list" is not the same collection as
node.ParentNode.ChildNodes.


Chris.
Author
29 Nov 2007 7:18 PM
Andrus
> No, it isn't because "list" is not the same collection as
> node.ParentNode.ChildNodes.

Chris,

Reply from Atsushi: It is like saying that when the IEnumerable implements
ICloneable, then a
cloned IEnumerable instance is a different collection and hence it is not
the
same collection of the IEnumerable. That makes no sense.

So this is bug.

Andrus.
Author
29 Nov 2007 7:47 PM
Chris Shepherd
Andrus wrote:
>> No, it isn't because "list" is not the same collection as
>> node.ParentNode.ChildNodes.
>
> Chris,
>
> Reply from Atsushi: It is like saying that when the IEnumerable implements
> ICloneable, then a
> cloned IEnumerable instance is a different collection and hence it is not
> the
> same collection of the IEnumerable. That makes no sense.

Actually, it does. A cloned IEnumerable instance is *not* the same
IEnumerable, by nature. It may have references to the same data, but it
does not necessarily contain the same list of references. If you remove
items from the newly cloned instance, it won't affect its progenitor,
and vice versa. Kind of the point of clone, really.

> So this is bug.

No, it isn't. You are functionally working with two different
IEnumerable objects. Below is an example of effectively what your
original code is doing -- removing a subset of items in one list from
another list.


Chris.



class General
{
     class ClassA
     {
         public string name;

         public ClassA(string nm) { this.name = nm; }
     }

     static void Main(string[] args)
     {
         List<ClassA> listOne = new List<ClassA>();
         List<ClassA> listTwo = new List<ClassA>();

         ClassA a = new ClassA("A");
         ClassA b = new ClassA("B");
         ClassA c = new ClassA("C");
         ClassA d = new ClassA("D");
         ClassA e = new ClassA("E");

         listOne.AddRange(new ClassA[] { a, b, c, d, e });
         listTwo.AddRange(new ClassA[] { a, c, d });

         string msg = "Start Length of listOne: " +
             listOne.Count.ToString() +
             "\nStart Length of listTwo: " +
             listTwo.Count.ToString() +
             "\nWhat is removed:\n";
         foreach (ClassA z in listTwo)
         {
             msg += z.name + "\t";
             listOne.Remove(z);
         }

         Console.WriteLine(msg + "\nLength of listOne: " +
             listOne.Count.ToString() +
             "\nLength of listTwo: " +
             listTwo.Count.ToString());
     }
}
Author
29 Nov 2007 7:59 PM
Family Tree Mike
Show quote
"Andrus" wrote:

> While iterating a collection it is not allowed to remove its element.
> However code below runs *without* (!) error in .NET 2.0 and 3.5
>
> There could be some buggy IEnumerable implementation that fails to report
> errorneous
> removal of collection content
>
> Please confirm, is this .NET bug ?
>
> Andrus.
>
>
> using System;
> using System.Windows.Forms;
> using System.Xml;
>
> public class Test
> {
>     [STAThread]
>     static void Main()
>     {
>         try
>         {
>             XmlDocument xDoc = new XmlDocument();
>             xDoc.PreserveWhitespace = false;
>             xDoc.LoadXml(xml);
>             XmlNodeList list = xDoc.SelectNodes("//comment()");
>             foreach (XmlNode node in list)
>             {
>                 node.ParentNode.RemoveChild(node);
>             }
>         }
>         catch (Exception ex)
>         {
>             Clipboard.SetText(ex.ToString());
>             MessageBox.Show(ex.ToString());
>         }
>     }
>
>     const string xml = @"<?xml version=""1.0"">
> <Report><!-- --></Report>
>     ";
>
> }
>
>

Though it is not advised to do what you have shown, I have never known it to
be illegal/not allowed.


Show quote
>

AddThis Social Bookmark Button