CasperT
CasperT

Reputation: 3475

add indexing to custom list

I have the following list:

public class MyQueue : IEnumerable<int>
{
    private Node Head { get; set; }
    private Node Tail { get; set; }

    public MyQueue()
    {
        Head = null;
    }

    public void Add(int item)
    {
        Enqueue(item);
    }

    public void Enqueue(int item)
    {
        var newItem = new Node { Data = item };

        if (Head == null)
        {
            Head = newItem;
            Tail = newItem;
            return;
        }

        Node last = Tail;
        last.Next = newItem;
        Tail = newItem;
    }
    public IEnumerator<int> GetEnumerator()
    {
        Node current = Head;
        while (current != null)
        {
            yield return current.Data;
            current = current.Next;
        }
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    private class Node
    {
        public int Data;
        public Node Next;
    }
}

There are other methods, but they do not matter in this scenario. I'd like to add indexing to this list.

So I can do something like:

var q = new MyQueue() {1, 2};
Console.WriteLine(q[0]); //1

What do I need to implement?

Upvotes: 0

Views: 4349

Answers (5)

jason
jason

Reputation: 241641

You need to implement an indexer. An indexer enables you to access a class, struct or interface as if it were an array. The syntax is as follows:

public int this[int index] {
    get {
        // obtain the item that corresponds to this index
        // return the item
    }
    set { 
        // set the value of the item that corresponds to 
        // index to be equal to the implicit parameter named "value"
    }
}

Here's an explicit example for your case:

public class MyQueue : IEnumerable<int> {
    // ...
    public int this[int index] {
        get {
            if (index < 0 || index > this.Count() - 1) {
                throw new ArgumentOutOfRangeException("index");
            }
            return this.Skip(index).First();
        }
        set {
            if (index < 0) {
                throw new ArgumentOutOfRangeException("index");
            }
            Node current = Head;
            int i = 0;
            while (current != null && i < index) {
                current = current.Next; i++;
            }
            if (current == null) {
                throw new ArgumentOutOfRangeException("index");
            }
            current.Data = value;
        }
    }
}    

Upvotes: 3

SLaks
SLaks

Reputation: 887453

Write a this property, like this: (pun intended)

public int this[int index] {
    get {
        return something;
    }

    //Optionally:
    set {
        something = value;
    }
}

Also, you should probably implement IList<int>. (Note, though, that the Count property would require a loop)

Upvotes: 1

mancaus
mancaus

Reputation: 3001

public int this[int index]
{
    get
    {
        return this.Skip(index).FirstOrDefault();
    }
}

Upvotes: 5

Darren Kopp
Darren Kopp

Reputation: 77627

you need to make a property like this:

public int this[int index]
{
    get {
        // code to return value
    }
}

Upvotes: 6

Jon Seigel
Jon Seigel

Reputation: 12401

Implement the this operator.

Upvotes: 1

Related Questions