[ACCEPTED]-How to create a 1-Dimensional Array in C# with index starting at 1-indexing
You can make a non-zero-based array in C#, but 16 the useage of it is kind-of obnoxious. It 15 is definitly not a simple substitute for 14 a normal (i.e., zero-based single dimentional) array.
// Create the array.
Array myArray = Array.CreateInstance(typeof(double), new int[1] { 12 }, new int[1] { 1 });
// Fill the array with random values.
Random rand = new Random();
for (int index = myArray.GetLowerBound(0); index <= myArray.GetUpperBound(0); index++)
{
myArray.SetValue(rand.NextDouble(), index);
}
// Display the values.
for (int index = myArray.GetLowerBound(0); index <= myArray.GetUpperBound(0); index++)
{
Console.WriteLine("myArray[{0}] = {1}", index, myArray.GetValue(index));
}
The 13 GetValue/SetValue syntax that is required 12 for this is uglier than subtracting one 11 from a vector index at each occurance.
If 10 a value type is stored in the array, then 9 it will be stored in consecutive position 8 just as in a regular array, but the getter 7 and setter will require boxing of the values 6 (unless there is some compiler magic that 5 I am not aware of). And the getter will 4 usually require a cast (just to make it 3 even uglier).
double myValue = (double)myArray.GetValue(index);
Also note that the correct 2 comparison for GetUpperBound
is <=
, unlike Length
which is compared 1 with <
.
Non-Zero based arrays DO exist in C, and 18 there IS a way to create a 1's (or whatever) based 17 array.
I fully agree that they are messy, and 16 they should not be used for anything other 15 than legacy stuff, but they are ESSENTIAL 14 to interact with old COM libraries.
The 13 most common place to run into this is working 12 with the Microsoft.Office.Interop.Excel.Range 11 object in the Excel library which still 10 uses the old DCOM interface underneath.
Example:
/// <summary>
/// Makes the equivalent of a local Excel range that can be populated
/// without leaving .net
/// </summary>
/// <param name="iRows">number of rows in the table</param>
/// <param name="iCols">number of columns in the table</param>
/// <returns>a 1's based, 2 dimensional object array which can put back to Excel in one DCOM call.</returns>
public static object[,] NewObjectArray(int iRows, int iCols)
{
int[] aiLowerBounds = new int[] { 1, 1 };
int[] aiLengths = new int[] { iRows, iCols};
return (object[,])Array.CreateInstance(typeof(object), aiLengths, aiLowerBounds);
}
In 9 this case, the reason this code is necessary 8 is each DCOM call to excel is a cross-process 7 call, and if you were to access cells one-at-a-time, you'd 6 incur huge overhead, (either retrieving 5 or setting values). An Excel range is a 4 1's based 2 dimensional array, and if one 3 creates the array, and populates it locally, it 2 can be pushed to excel in one cross-process 1 call, creating an enormous performance improvement.
If anybody is still looking for a one-based 11 array implementation, here is a one-dimensional 10 generic one-based array, which is just a 9 wrapper type on a regular array:
There is 8 also a two-dimensional version, but no higher 7 dimensional versions as of yet (this code 6 was written to support Excel, so 2D was 5 all that was needed):
Both of these types 4 have test written for them in an associated 3 test project under the same repo:
https://github.com/ColmBhandal/CsharpExtras/tree/master/CsharpExtrasTest/OneBased
Disclaimer: these 2 repos are hosted on my personal GitHub account 1 and are open source.
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.