Question

I'm getting a stack overflow from using the get/set part of my index. I've tried putting the values into a list instead in the get set but with bad results.

class TrackList : CollectionBase
{
    public Tracks this[int i]
    {
        get
        {
            return this[i];
        }
        set
        {
            this[i] = value;
        }
    }
}

Main:

class Program
{
    public static void Main(string[] args)
    {
        TrackList l1 = new TrackList();
        l1[0] = new Tracks(1, "Random");
        l1[1] = new Tracks(2, "Random");
        l1[2] = new Tracks(3, "Random");
    }
}

Answer: I was looping inside my get/set. Here is the working code:

class TrackList : CollectionBase
{
    public Tracks this[int i]
    {
        get
        {
            return (Tracks) List[i];
        }
        set
        {
            List[i] = value;
        }
    }
}

Main:

class Program
{
    public static void Main(string[] args)
    {
        TrackList l1 = new TrackList();
        l1.Add(new Tracks(1, "random"));
        l1.Add(new Tracks(2, "random"));
        l1.Add(new Tracks(3, "random"));
    }
}
Was it helpful?

Solution

You are recursively calling the property indexer an infinite number of times. I think you want this:

public Tracks this[int i]
{
    get
    {
        return (Tracks) List[i];
    }
    set
    {
        List[i] = value;
    }
}

Then, add your items:

TrackList l1 = new TrackList();
l1.List.Add(new Tracks(1, "Random"));
l1.List.Add(new Tracks(2, "Random"));
l1.List.Add(new Tracks(3, "Random"));

Then replace an item using the indexer:

l1[1] = new Tracks(2, "Replacement");

Or retrieve an item using the indexer:

var firstItem = l1[0];

Trying to use l1[i] where i <= l1.Count will produce an ArgumentOutOfRangeException, as you would expect.

OTHER TIPS

First, your stackoverflow exception is caused by calling your indexer on itself:

    return this[i];

You call your indexer which calls your indexer which then calls your indexer and so on.

Your main program should look like this:

class Program
{
    public static void Main(string[] args)
    {
        TrackList l1 = new TrackList();
        l1.Add(new Tracks(1, "Random"));
        l1.Add(new Tracks(2, "Random"));
        l1.Add(new Tracks(3, "Random"));
    }
}

You can't just access indexes which not yet exist in your list.

After you added its ok to get a certain element from it:

Tracks t = l1[2]; // to get the third element in your list

DO NOT use list.Add in an indexer setter. This violates the least astonishment principle.

Otherwise the only possibility is to create a list with predefined number of null elements in your constructor. But I don't recommend this.

TrackList l1 = new TrackList(3); // in constructor create a list of 3 null elements

The correct way for the whole approach is using List<Tracks> and you are done.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top