Question

Doing some code reading and stumbled upon this snippet that I haven't seen before:

public SomeClass {
  public someInterface this[String strParameter] {
    get {
      return SomeInternalMethod(strParameter);
    }
  }
}

It looks like it is called as follows:

SomeClass _someClass = new SomeClass();
SomeInterface returnedValue = _someClass["someString"];

I am interested in where this function would be appropriate or what the intent of writing in this style. For example why would this be preferred over simply calling the function?

Was it helpful?

Solution

See the language specification, section 10.9, which states:

An Indexer is a member that enables an object to be indexed in the same way as an array.

Indexers and properties are very similar in concept, but differ in the following ways:

  • A property is identified by its name, whereas an indexer is identified by its signature.
  • A property is accessed through a simple-name (§7.5.2) or a member-access (§7.5.4), whereas an indexer element is accessed through an element-access (§7.5.6.2).
  • A property can be a static member, whereas an indexer is always an instance member.
  • A get accessor of a property corresponds to a method with no parameters, whereas a get accessor of an indexer corresponds to a method with the same formal parameter list as the indexer.
  • A set accessor of a property corresponds to a method with a single parameter named value, whereas a set accessor of an indexer corresponds to a method with the same formal parameter list as the indexer, plus an additional parameter named value.
  • It is a compile-time error for an indexer accessor to declare a local variable with the same name as an indexer parameter.
  • In an overriding property declaration, the inherited property is accessed using the syntax base.P, where P is the property name. In an overriding indexer declaration, the inherited indexer is accessed using the syntax base[E], where E is a comma separated list of expressions.

OTHER TIPS

It seems like a lot of the answers are focusing on what an indexer is, not why you would want to use one.

As far as I'm concerned, here is the motivation to use an indexer:

You are working on a class that has a collection of some sort, but you want the class to appear to users (consumers of the class) as if it is a collection.

The best example I can think of is the DataRow class in ADO.NET. If you want to get the value of the fifth cell of a DataRow, you can either use DataRow.Item[4] or DataRow[4]. The latter form is a convenient and logical shortcut, and it shows off pretty nicely why you'd want to use an indexer. To the user, the DataRow can be thought of as just a collection of cells (even though it is really more than that), so it makes sense to be able to get and set cell values directly, without having to remember that you are actually getting/setting an Item.

Hope that helps.

In many cases, the 'index' syntax makes a lot of sense. It is particularly useful if the SomeClass represents some sort of collection.

It allows you to do associative array lookups (a.k.a. "dictionary style"), just as you mentioned in your question.

And that's the whole point. Some people like that, particularly people coming from languages that have it built in, like Python or PHP

The "this" keyword is an indexer

from http://msdn.microsoft.com/en-us/library/6x16t2tx.aspx

"Indexers allow instances of a class or struct to be indexed just like arrays. Indexers resemble properties except that their accessors take parameters."

You may have already stumbled across something similar before:

var myList = new List<string>();
myList.Add("One");
myList.Add("Two");
myList.Add("Three");

for(int i = 0; i < myList.Count; i++) {
    string s = myList[i];
}

The indexer is the "primary key" of an object that implements a collection. It's just a shorthand way for writing a function like .GetValue(index) - syntactic sugar, if you want. But it also makes the intent clear.

It an implementation of the index operator [ ].

It's an operator overload. Useful if you are writing a collection class for example where it would make sense to access it using array notation, e.g. collection[someIndex].

You could of course write a collection.GetElement(someIndex) function equivalent, but it's a style/readability thing.

Well you could use this method in a key-value pair class.

I am not sure what the analogous class is in c#, but in c++ STL, there is the map class where you call the method with the SomeObject["key"] and it will return the "value" associated with that key.

That's called an Indexer, they allow you to use List<>, ArrayList, Dictionary<> and all the other collections using an array syntax.

It's just syntactic sugar, but it gives some readability when used right.

In my opinion, it's just a syntax convenience. Where would you NOT use it:

public SomeClass {
  private int[] nums;
  public GetVal this[int ind] {
    get {
      return nums[ind]; // this is pointless since array is already indexed
    }
  }
}

Where would you benefit from it:

public Matrix {
  private Dictionary<string, double> matrixData; // Matrix indecies, value
  public double this[int row, int col] {
    get {
      return matrixData[string.Format("{0},{1}", row, col)];
    }
  }
}

As you can see, for some reason, your data is a Dictionary indexed with a string key and you wish to call this with two integer indecies and still do not want to change your data type:

Matrix m = new Matrix();
...
Console.WriteLine( m[1,2] );
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top