The Pathological Programmer: Recursing with indexers
Ah yes, it’s time for the Pathological Programmer. The PP has found a fun new way of creating an infinite loop. And with new ways of creating infinite loops come new ways of recursion!
C# has a language feature called “indexers”. You know about array indexers right? You have an array of ten integers, you want the fifth one. Simple: intArray[4] gives you the value, because you paid attention in class and you know that for some stupid reason arrays start with 0 instead of 1 so if you want the fifth one you have to give it an index of 4. The point is, the “indexer” is the brackets. The index is the 4. And the array is intArray.
Another way of looking at arrays is like a little row of boxes. If I ask for the value in box number 4, I get the value in box number 4. Simple, easy.
What is actually happening behind the scenes is this. When you create an array in C or C++ you create a huge chunk of memory that is the size of all of the objects you want to store. Unbeknownst to you (unless you already knownst this, I suppose), your program associates intArray with the memory location of the first byte of your huge chunk of memory. When you ask for intArray[4], the compiler multiplies the 4 by the size of an integer, and then adds that value to the memory location of the first byte. Shazam! That’s the location in memory where the fifth integer of your array is stored.
See? This is why arrays start at 0, because when you multiply 0 to the size of your object you’re storing, you get 0, which is added to the base address of the array, giving the base address of the array… which is where the first element of your array is stored. Now you also see why you don’t want to go off the end of an array… because the computer is just adding the numbers you give it blindly without doing any sanity checking. If you tried to access intArray[500] your program will happily try to fetch the 500th integer past the base address of the array. The only thing stopping you is the operating system, and it’s a good thing too because maybe Quicken stuck my credit card number 500 integers away from your array, and you’re trying to steal it from me, you wily hacker you. Because computers mix data and code together in memory, maybe the operating system has some important code to execute 2000 bytes away (which is the size of 500 integers, at least on my machine), and you’re trying to replace it with your code which formats my C:\ drive and prints “John’s a weenie!” on my computer screen. Fortunately, the operating system is going to put a stop to your antics, unless you found a way to exploit a bug in the OS in which case you’ve found what’s called a buffer overflow and now I’m screwed, hey, why is my hard drive making so much nois*#(@>,,,John’s a weenie!8982 3@*(!!!9++NO CARRIER
Okay, I’m getting off track. Back to arrays.
C# is a little more object oriented than C or C++. If you’re unfamiliar with the concept of object oriented programming, you need to stop thinking of C# arrays as being these simple constructs that you understand. Because in C#, if I want an array of something, I create an instance of the Array class.
If I have an Array of ten integers in C#, I can still get the fifth one by typing intArray[4]. My code looks the same, and it does the same thing. But intArray is now an object. The brackets act like funny looking parentheses, kind of like calling a function. And the index is like a function argument. You can’t assume that all of your objects are next to each other in memory any more. And the Array class does bounds checking on your objects to keep you from going off the edge of the array.
But what’s cool about this is that in C#, any object can have an indexer. Not only that, the indexes don’t have to be integers, they can be strings or floats or any other object, even something stupid like StackOverflowExceptions. And, for the purposes of being pathological, your objects don’t even have to act like a normal arrays anymore. You can throw exceptions every time someone uses your indexer with an index of 13, for example. And so on.
Of course, you can call an indexer within an indexer by doing this[index]. You see where this is going…
using System;
namespace PathologicalIndexers
{
class MagicalRecursingIndexer
{
private int acc = 0;
public int this[int index]
{
get
{
if (index == 0)
{
int i = acc;
acc = 0;
return i;
}
else
{
acc += index;
return this[index-1];
}
}
}
}
class Program
{
static void Main(string[] args)
{
MagicalRecursingIndexer maj =
new MagicalRecursingIndexer();
System.Console.Write(
\"The sum of all of the integers from 1 to 100: \");
System.Console.WriteLine(maj[100]);
System.Console.ReadLine();
}
}
}
This prints
The sum of all of the integers from 1 to 100: 5050
to the console.

August 6th, 2005 at 8:18 am
Are the brakets an instance of an overloaded operator? Would it be a better idea to force someone to say “myArray.Item(5)” instead of “myArray(5)” if the former is what is actually happening?
August 8th, 2005 at 12:06 am
No, indexers are not overloaded operators in C#. Above you’ll find the syntax of defining an indexer; here is the syntax for overloading an operator:
public static Thingie operator *(Thingie thing1, Thingie thing2){
// Thingie multiplication implementation
}
Also, an indexer is only kind of like calling a function. You can get a value, sure, but you can also set the value at an index.
For an example (taken straight from the MSDN docs on indexers), you can make a class that treats a file as an array of bytes. Of course you don’t want to read the entire file into memory; what if it’s gigabytes in size? So instead you create a FileByteArray class that has an indexer and acts like an array, but behind the scenes it uses file I/O to get and set your bytes.