Reputation: 281
This is the main class
class Program
{
static void Main(string[] args)
{
MyArray fruit = new MyArray(-2, 1);
fruit[-2] = "Apple";
fruit[-1] = "Orange";
fruit[0] = "Banana";
fruit[1] = "Blackcurrant";
Console.WriteLine(fruit[-1]); // Outputs "Orange"
Console.WriteLine(fruit[0]); // Outputs "Banana"
Console.WriteLine(fruit[-1,0]); // Output "O"
Console.ReadLine();
}
}
and here is the class for the indexer:
class MyArray
{
int _lowerBound;
int _upperBound;
string[] _items;
public MyArray(int lowerBound, int upperBound)
{
_lowerBound = lowerBound;
_upperBound = upperBound;
_items = new string[1 + upperBound - lowerBound];
}
public string this[int index]
{
get { return _items[index - _lowerBound]; }
set { _items[index - _lowerBound] = value; }
}
public string this[int word, int position]
{
get { return _items[word - _lowerBound].Substring(position, 1); }
}
}
So, multiDimensional indexer in defined in the 'Class MyArray'
I am not able to understand how this is working when we pass '-1' as the value of 'word' to the indexer. The value for '_lowerbound' is '-2'. So it means, the value for the return should be _items[-1 - (-2)], which makes it _items[1].
But actually it is pointing to -1 index of fruits i.e. Orange.
Please clear my doubt.
Upvotes: 2
Views: 379
Reputation: 55956
This is you private array _items
:
0 1 2 3 ┌────┐┌────┐┌────┐┌────┐ │ Ap ││ Or ││ Ba ││ Bl │ └────┘└────┘└────┘└────┘
This is how it appears using the indexer:
-2 -1 0 1 ┌────┐┌────┐┌────┐┌────┐ │ Ap ││ Or ││ Ba ││ Bl │ └────┘└────┘└────┘└────┘
The value for
_lowerbound
is-2
.So it means, the value for the return should be
_items[-1 - (-2)]
, which makes it_items[1]
.
That's correct.
But actually it is pointing to
-1
index of fruits i.e. Orange.
That's wrong. It is pointing to _items[1]
, i.e. Orange.
Indexers are a simple way to permit a class to be used like an array. Internally, you can manage the values presented in any fashion you wish.
_items
is a zero-based array with the same length as the created MyArray
object.
The indexer is just interpreting the index number supplied and map it against this underlying array.
Upvotes: 4
Reputation: 64487
This isn't a multi-dimensional array in the expected sense, it just looks like one.
Updated Answer:
It looks like you expect: fruits[-1, 0]
to point to the same element as fruits[1] = "Blackcurrent"
. Unfortunately this isn't the case as in both instances you are actually using custom indexers, both of which modify your provided index values.
The custom indexers on MyArray
are mutating the index values you are supplying before they get to the underlying string[]
. This is where the confusion has come in, you are not taking into account the code in the custom indexers:
public string this[int index]
{
get { return _items[index - _lowerBound]; }
set { _items[index - _lowerBound] = value; }
}
public string this[int word, int position]
{
get { return _items[word - _lowerBound].Substring(position, 1); }
}
Don't confuse array index in primitive arrays with indexing on custom implementations. You can do whatever you like with the latter, it is basically just syntactic sugar over method calls. You have an indexer that takes an int
, that means any valid int
is a valid argument for the indexer (though maybe not for the underlying primitive array string[]
).
Your index implementation subtracts lowerBound
from both the get and the set, so the same index supplied at the set will result in the same element as the index supplied for the get.
The second indexer taking two parameters is doing the same index modification so will result in the same element (Orange)...
Where is the confusion? Are you expecting the second parameter of...
public string this[int word, int position]
...to somehow affect what element is returned? It is used in the Substring
call of the element returned by the ordinal word - lowerBound
, it does not affect what element is chosen.
Upvotes: 2
Reputation: 3430
Arrays in .Net languages, like C#, can't have items with negative indexes.
To circumvent this, this array class moves the item with the lowest index (index of _lowerBound
) to 0. So when you access the internal array, you'll have to substract _lowerBound
from the index, so it will never try to pass a negative index.
This is why -1 will actually be at 1 in the internal array, because -1 - (-2) equals to 1.
Edit: I'm not sure why you think there should be a difference between your class' two indexers. They both use _items[index - _lowerBound]
to access the underlying .Net array.
Other than the String.Substring call, there's no difference between the two indexers.
Try changing the code of the second indexer so it calls the first indexer, you'll see it returns the same character. (http://ideone.com/sFmDo)
Upvotes: 1
Reputation: 22945
The index calculated in this[int] and this[int,int] is the index as you need it in the _items array, and this array starts at index 0. So the second item there is indeed index=1, which is Orange.
Update: _items[-1] doesn't exist, this array starts at index 0.
Upvotes: 1