@Chris, Your statement about .Length being costly in .NET is actually untrue and in the case of simple types the exact opposite.
int len = somearray.Length;
for(i = 0; i < len; i++)
{
somearray[i].something();
}
is actually slower than
for(i = 0; i < somearray.Length; i++)
{
somearray[i].something();
}
The later is a case that is optimized by the runtime. Since the runtime can guarantee i is a valid index into the array no bounds checks are done. In the former, the runtime can't guarantee that i wasn't modified prior to the loop and forces bounds checks on the array for every index lookup.