During a course I gave some time ago, one of my students encountered a strange situation while using a DataTable. We were creating new rows for a DataTable, and not adding those rows to the Rows collection of the table, they were being set aside so to speak. During the creating of new rows, it was possible Clear was called in order to clear the table of rows. Since the rows that were set aside were not actually added to the table, we didn't expect them to be altered. But strangly it did. Two distinct DataRow objects created using NewRow() were pointing to the same piece of data, so when one was updated, so was the other.
Let's examine some of the code and determine what happened:
DataTable table = new DataTable("Test");
table.Columns.Add("Column1", typeof(string));
DataRow row = table.NewRow();
row[0] = "TestValue"; #if SHOW_ERROR
table.Clear();
#endif
DataRow otherRow = table.NewRow();
otherRow[0] = "SomeOtherValue";
Console.WriteLine(row[0] == otherRow[0]);
First, we create a simple DataTable, with a DataColumn. Next we create a row for the table using the NewRow() method, we also fill the row with data. Next another row is created using NewRow(), and filled as well. Notice that both rows are not added to the table, they are just created and put on the side. The compiler directive SHOW_ERROR will toggle the error, but what error exactly?
When the Clear() method is called in between two rows which have been created using NewRow(), both the first and second row will reference the same data, while we distinctly created both rows using the NewRow() method! I expect the 'row' and 'otherRow' to always store different data, but the final check will show that they are equal. Even more interesting is to compare Object.Equals(row, otherRow). This will return false!
It turns out that, when you decompile the DataRow class, that the DataRow isn't responsible for storing the data itself, the DataColumn is responsible for this. This is why Object.Equals doesn't return true (duh, 2 instances). The DataRow created using NewRow indexes a specific position in the DataColumn's data, and this index is what gets reset when calling Clear. Hence, if you call Clear between two calls to NewRow(), both rows will reference the same data.
You would expect that rows that have been created using NewRow, aren't influenced by Clear when you haven't added them to the DataTable yet. But all rows (including newly created, but un-added) reference a piece of data in the DataColumn / DataTable.
Read about this on the MSDN feedback center