5

I'm not entirely sure if I have all the terminology correct so forgive me if I'm wrong. I was wondering if it would be possible to send an argument(s) to the method. Take the following for example.

public item (int index)  
{  
    get { return list[index]; }  
    set { list[index] = value; }  
}

I know that as it is, it will error. What I'm asking is if there is some way to get it working. Any suggestions or should I figure out some way around it?

Thanks in advance.

jason
  • 236,483
  • 35
  • 423
  • 525
Nyight
  • 231
  • 1
  • 7
  • 15

7 Answers7

21

Try this:

// This returns an instance of type "Foo",
// since I didn't know the type of "list".
// Obviously the return type would need to
// match the type of whatever "list" contains.
public Foo this[int index]
{
    get { return list[index]; }
    set { list[index] = value; }
}

This is C#'s indexer syntax and it has some limitations (it's not as flexible as VB.NET's parameterful properties) but it does work for your specific example.

Martin.
  • 10,494
  • 3
  • 42
  • 68
Andrew Hare
  • 344,730
  • 71
  • 640
  • 635
6

As others have shown, you can turn it into an indexer - which can have multiple parameters, by the way.

What you can't do is name an indexer in C#... although you can in VB. So you can't have two indexers, one called Foo and the other called Bar... you'd need to write properties which returned values which were themselves indexable. It's a bit of a pain, to be honest :(

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    +1 To you. I never quite understood this though - in VB the syntax for calling a parameterful property looks just like a method call (which of course it is) so what is the advantage? Just so it would look and act like a method but would have "Property" metadata in the assembly? – Andrew Hare Sep 24 '09 at 13:22
  • 1
    @Andrew You can use assignment syntax with properties: Product.Description("en-US") = "Tea" – alex Sep 24 '09 at 14:22
  • 1
    Which of course you could do as Product.SetDescription("en-US", "Tea"). The argument against parameterful properties is exactly the same as against properties in general - they're just method calls, you could call them as methods (as in Java) etc. – Jon Skeet Sep 24 '09 at 14:39
  • That makes sense - I guess the only thing that is strange is that at least C#'s indexers _look_ different which aids in readability if nothing else. The VB syntax is simply confusing as it is indistinguishable from a method. – Andrew Hare Sep 24 '09 at 14:47
5

This is called indexer property

public int this [int index]  
{      
     get { return list[index]; }      
     set { list[index] = value; }  
}
Svetlozar Angelov
  • 21,214
  • 6
  • 62
  • 67
3

I think what you might be looking for is:

public Something this[int index]
{
    get
    {
         return list[index];
    }
    set
    {
         list[index] = value;
    }
}
ilivewithian
  • 19,476
  • 19
  • 103
  • 165
1

For the record, Whilst the other answers are valid, you might also want to consider using the following approach:

public IList<Something> items { get; set; }

This could then be used as follows:

Something item = myFoo.items[1];

The other answers would be used in the following, slightly different, way:

Something item = myFoo[1];

The one you want depends on what exactly you are trying to achieve, which is difficult to determine without seeing the rest of the code.

Luke Bennett
  • 32,786
  • 3
  • 30
  • 57
1

Besides the indexer that has been mentioned several times now, another possibility is to make a custom class with an indexer and return an instance of it as a property.

Example:

public class IntList
{
    public IntList(IEnumerable<int> source)
    {
        items = source.ToArray();
        Squares = new SquareList(this);
    }

    private int[] items;

    // The indexer everyone else mentioned
    public int this[int index]
    {
        get { return items[index]; }
        set { items[index] = value; }
    }

    // Other properties might be useful:
    public SquareList Squares { get; private set; }

    public class SquareList
    {
        public SquareList(IntList list)
        {
            this.list = list;
        }

        private IntList list;

        public int this[int index]
        {
            get { return list.items[index] * list.items[index]; }
        }
    }
}
Joren
  • 14,472
  • 3
  • 50
  • 54
0

You can use indexator for solving this problem

public object this[string name]
        {
            get
            {
                int idx = FindParam(name);
                if (idx != -1)
                    return _params[idx].Value;

                throw new IndexOutOfRangeException(String.Format("Parameter \"{0}\" not found in this collection", name));
            }
            set 
            { 
                int idx = FindParam(name);
                if (idx != -1)
                    _params[idx].Value = value;
                else
                    throw new IndexOutOfRangeException(String.Format("Parameter \"{0}\" not found in this collection", name));
            }
        }
msi
  • 3,202
  • 4
  • 27
  • 37