To put it simply, Idexers is a technique that you can use to allow a class to behave in a similar way to an array, by allowing you can access values by using an index.
- generally you would only do this if conceptually the class is supposed to behave like an array, its primary function is to hold a single collection of other objects.
A common scenario is when the class is a wrapper for an internal array variable that you do not want to directly expose. We try to avoid classes inheriting from arrays or IEnumerable because there is a lot of functionality to implement, but wrapping an array for the purposes of adding additional functionality can make a lot of sense.
temps
in your syntax public float temps this[int index]
doesn't make sense, and is not necessary because a class can only have a single indexer of each type.
Instead of using an indexer, if the temps
field was exposed as public, then you could use this syntax instead to access the value for the index of 5:
TempratureRecord oTest = new TemperatureRecord();
var tempAtIndex5 = oTest.temps[5];
But now you have access to the temps
variable itself, meaning you could reassign it altogther.
Do not mistake that example as the only way to expose values from internal arrays, if you had multiple arrays then you can expose them in different ways, generally NOT by using an indexer.
If the indexer only exposes an internal array, but offers nothing more, then that's probably not a great reason to use them at all.
You can have an indexer of say type string
and a separate indexer of type int
, this is a common pattern if the internal array is an array of objects that might have both a unique string and int property that can be used to identify the correct object to return.
However you would not generally do this just because you have an array of ints and an array of strings. The general expectation of Indexers is that if there are multiple indexers, we are offering the caller a different way to access the same conceptual list of objects, and indeed to target the same object in different ways, perhaps because we do not know the index of that object in the internal array.
An example of how multiple indexers might be used to access the same internal array, but showing how the index passing in doesn't have to be the index at all that is used internally:
Note: by doing it this way, it may not make sense to allow a setter at all
public class Person
{
string Name { get; set; }
int Id { get; set; }
}
public class People
{
private Person[] _backingStore;
/// <summary>Instantiate a new list of people</summary>
public People(params Person[] persons)
{
_backingStore = persons;
}
/// <summary> Return a person from this list by Id </summary>
public Person this[int id]
{
get{
return _backingStore.Where(p => p.Id == id).FirstOrDefault();
}
}
/// <summary> Return a person from this list by Name </summary>
public Person this[string name]
{
get{
return _backingStore.Where(p => p.Name == name).FirstOrDefault();
}
}
}
...
People list = new People(
new Person(){ Id = 26, Name = "Hassan" },
new Person(){ Id = 101, Name = "John Skeet" }
);
var john = list["John Skeet"];
var alsoJohn = list[101];
var no1 = list["someone else"];
var hassan = list["Hassan"];