Hi there,
I would in some respect disagree with Wiliams reply. Especiallly with:
inserts a fixed address of the start of the DataTable
structure at design time when it knows the location (as in Tables(0))
Addresses are known at the runtime. The only thing fixed in this case is
offset from the location referenced by arraylist that holds the pointers
to
tables. This is disassembled and translated code for both iterators from
the
System.Data assembly:
public DataColumn get_Item(int index)
{
DataColumn column1;
try
{
column1 = (DataColumn) this._list[index];
}
catch (ArgumentOutOfRangeException)
{
throw ExceptionBuilder.ColumnOutOfRange(index);
}
return column1;
}
public DataColumn get_Item(string name)
{
if (name == null)
{
throw ExceptionBuilder.ArgumentNull("name");
}
DataColumn column1 = this.columnFromName[name] as DataColumn;
if (column1 == null)
{
int num1 = this.IndexOfCaseInsensitive(name);
if (0 <= num1)
{
return (DataColumn) this._list[num1];
}
if (-2 == num1)
{
throw ExceptionBuilder.CaseInsensitiveNameConflict(name);
}
}
return column1;
}
internal int IndexOfCaseInsensitive(string name)
{
int num3 = this.table.GetSpecialHashCode(name);
int num2 = -1;
DataColumn column1 = null;
for (int num1 = 0; num1 < this.Count; num1++)
{
column1 = (DataColumn) this._list[num1];
if ((((num3 == 0) || (column1._hashCode == 0)) ||
(column1._hashCode == num3)) && (base.NamesEqual(column1.ColumnName, name,
false, this.table.Locale) != 0))
{
if (num2 == -1)
{
num2 = num1;
}
else
{
return -2;
}
}
}
return num2;
}
As you can see both methods DataTableCollection[Int32] and
DataTableCollection[String] follow the same path and the end result is
always
this._list[index] which behind the scenes should be equivalent to address
(this._list->InternalArray) + index * sizeof(DataTablePointer), where
sizeof(DataTablePointer) = 4. The only difference between this method is
that
offset for Tables[0] is known, so the only thing runtime must do is to
jump
to the location pointed by this._list->InternalArray (and get next 4 bytes
which actually is a pointer to the datatable), whilst second method must
obtain offset by hastable lookup (or if it fails looping over items
comparing
table name), that's why the second method is slower. Therefore i disagree
with statement
If the compiler cannot determine the specified DataTable at compile time,
it
inserts code to look up the table in the Tables collection at
runtime --each
time it's referenced using a string or string variable.
Hope my reasoning doesn not look chaotic
Regards