Introduction
Indexers in C# (The definition)
Roadmap
Let’s recall our road map,
- Diving in OOP (Day 1): Polymorphism and Inheritance(Early Binding/Compile Time Polymorphism)
- Diving in OOP (Day 2): Polymorphism and Inheritance (Inheritance)
- Diving in OOP (Day 3): Polymorphism and Inheritance (Dynamic Binding/Run Time Polymorphism)
- Diving in OOP (Day 4): Polymorphism and Inheritance (All about Abstarct classes in C#)
- Diving in OOP (Day 5): All about access modifiers in C# (Public/Private/Protected/Internal/Sealed/Constants/Readonly Fields)
- Diving in OOP (Day 6): Understanding Enum in C# (A Practical Approach)
- Diving into OOP (Day 7): Properties in C# (A Practical Approach)
- Diving into OOP (Day 8): Indexers in C# (A Practical Approach)
- Diving into OOP (Day 9): Understanding Events in C# (An Insight)
Indexers (The explanation)

Lab 1
namespace Indexers { class Program { static void Main(string[] args) { Indexer indexer=new Indexer(); indexer[1] = 50; } } }
Lab 2
Indexer.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace Indexers
{
public class Indexer
{
public int this[int indexValue]
{
set
{
Console.WriteLine(“I am in set : Value is “ + value + “ and indexValue is “ + indexValue);
Console.ReadLine();
}
}
}
}
Program.cs
namespace Indexers { class Program { static void Main(string[] args) { Indexer indexer=new Indexer(); indexer[1] = 50; } } }
Output

Lab 3
Indexer.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace Indexers
{
public class Indexer
{
public int this[int indexValue]
{
set
{
Console.WriteLine(“I am in set : Value is “ + value + “ and indexValue is “ + indexValue);
}
get
{
Console.WriteLine(“I am in get and indexValue is “ + indexValue);
return 30;
}
}
}
}
Program.cs
using System;
namespace Indexers
{
class Program
{
static void Main(string[] args)
{
Indexer indexer=new Indexer();
Console.WriteLine(indexer[1]);
Console.ReadKey();
}
}
}
Output

Data-Types in Indexers
Lab 1
Indexer.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace Indexers
{
public class Indexer
{
public int Index;
public int this[string indexValue]
{
set
{
Console.WriteLine(“I am in set : Value is “ + value + “ and indexValue is “ + indexValue);
Index = value;
}
get
{
Console.WriteLine(“I am in get and indexValue is “ + indexValue);
return Index;
}
}
}
}
Program.cs
using System;
namespace Indexers
{
class Program
{
static void Main(string[] args)
{
Indexer indexer=new Indexer();
indexer[“name”]=20;
Console.WriteLine(indexer[“name”]);
Console.ReadKey();
}
}
}
Output

this
” property i.e. indexers have return value. In our example the return value was integer. The square brackets along with “this
” can also hold other data types and not only integer in the above mentioned example I tried to explain this using string parameter type for “this
” : public int this[string indexValue],
indexValue
” has a value “name”, like we passed in Main method of Program.cs. So one can have more than one indexers in a class deciding what should be the data type of the parameter value of array. An indexer, like properties follow same rules of inheritance and polymorphism.Indexers in interfaces
IIndexers
having following code,namespace Indexers { interface IIndexers { string this[int indexerValue] { get; set; } } }
IIndexers
interface,Indexer.cs
using System;
namespace Indexers
{
public class IndexerClass:IIndexers
{
readonly string[] _nameList = { “AKhil”,“Bob”,“Shawn”,“Sandra” };
public string this[int indexerValue]
{
get
{
return _nameList[indexerValue];
}
set
{
_nameList[indexerValue] = value;
}
}
}
}
indexerValue
. Let’s call this in our main method,Program.cs
using System;
namespace Indexers
{
class Program
{
static void Main(string[] args)
{
IIndexers iIndexer=new IndexerClass();
Console.WriteLine(iIndexer[0]);
Console.WriteLine(iIndexer[1]);
Console.WriteLine(iIndexer[2]);
Console.WriteLine(iIndexer[3]);
Console.ReadLine();
}
}
}

IndexerClass
, and we accessed that object array through indexer values like an array. It gives the names one by one.iIndexer[2] = "Akhil Mittal"; Console.WriteLine(iIndexer[2]);

Indexers in Abstract class
AbstractBaseClass
namespace Indexers { public abstract class AbstractBaseClass { public abstract string this[int indexerValue] { get; set; } } }
IndexerClass
using System;
namespace Indexers
{
public class IndexerClass:AbstractBaseClass
{
readonly string[] _nameList = { “AKhil”,“Bob”,“Shawn”,“Sandra” };
public override string this[int indexerValue]
{
get
{
return _nameList[indexerValue];
}
set
{
_nameList[indexerValue] = value;
}
}
}
}
Program.cs
Indexer
class.using System;
namespace Indexers
{
class Program
{
static void Main(string[] args)
{
AbstractBaseClass absIndexer=new IndexerClass();
Console.WriteLine(absIndexer[0]);
Console.WriteLine(absIndexer[1]);
Console.WriteLine(absIndexer[2]);
Console.WriteLine(absIndexer[3]);
absIndexer[2] = “Akhil Mittal”;
Console.WriteLine(absIndexer[2]);
Console.ReadLine();
}
}
}

Indexer Overloading
Indexer.cs

using System;
namespace Indexers
{
public class Indexer
{
public int this[int indexerValue]
{
set
{
Console.WriteLine(“Integer value “ + indexerValue + “ “ + value);
}
}
public int this[string indexerValue]
{
set
{
Console.WriteLine(“String value “ + indexerValue + “ “ + value);
}
}
public int this[string indexerValue, int indexerintValue]
{
set
{
Console.WriteLine(“String and integer value “ + indexerValue + “ “ + indexerintValue + “ “ + value);
}
}
}
}
Program.cs
using System;
namespace Indexers
{
class Program
{
static void Main(string[] args)
{
Indexer indexer=new Indexer();
indexer[1] = 30;
indexer[“name”]=20;
indexer[“address”,2] = 40;
Console.ReadLine();
}
}
}
Output

Point to remember
Static Indexers?
public static int this[int indexerValue] { set { Console.WriteLine("Integer value " + indexerValue + " " + value); } }
Point to remember
Inheritance/Polymorphism in Indexers
Indexer.cs

using System;
namespace Indexers
{
public class IndexerBaseClass
{
public virtual int this[int indexerValue]
{
get
{
Console.WriteLine(“Get of IndexerBaseClass; indexer value: “ + indexerValue);
return 100;
}
set
{
Console.WriteLine(“Set of IndexerBaseClass; indexer value: “ + indexerValue + “ set value “ + value);
}
}
}
public class IndexerDerivedClass:IndexerBaseClass
{
public override int this[int indexerValue]
{
get
{
int dValue = base[indexerValue];
Console.WriteLine(“Get of IndexerDerivedClass; indexer value: “ + indexerValue + “ dValue from base class indexer: “ + dValue);
return 500;
}
set
{
Console.WriteLine(“Set of IndexerDerivedClass; indexer value: “ + indexerValue + “ set value “ + value);
base[indexerValue] = value;
}
}
}
}
Program.cs
using System;
namespace Indexers
{
class Program
{
static void Main(string[] args)
{
IndexerDerivedClass indexDerived=new IndexerDerivedClass();
indexDerived[2] = 300;
Console.WriteLine(indexDerived[2]);
Console.ReadLine();
}
}
}
Output

IndexerBaseClass
having an indexer with its own get and set like we discussed in prior examples. There after a derived class is created named IndexerDerivedClass
, this derives from IndexerBaseClass
and overrides “this” indexer from base class, note that base class indexer is marked virtual, so we can override it in derived class by marking it “override” in derived class.The example makes call to indexer of base class. Sometimes when we need to override code in derived class in the derived class, we may require the base class indexer should be called first. This is just a situation. The same rule of run time polymorphism applies here , we declare base class indexer and virtual and derived class one as override. In “set” accessor of derived class, we can call base class indexer as base[indexerValue]
. Also this value is used to initialize the derived class indexer as well. So the value is stored in “value” keyword too. So, indexDerived[2]
in Main()
method of Program.cs gets replaced to base[2]
in “set” accessor. Whereas In “get” accessor it is vice versa, we require to putbase[indexerValue]
to right hand side of equal sign. The “get” accessor in base class returns a value, i.e. 100, which we get in dValue
variable..NET Framework and Indexers
Point to remember
Properties vs Indexers
Property | Indexer |
Allows methods to be called as if they were public data members. | Allows elements of an internal collection of an object to be accessed by using array notation on the object itself. |
Accessed through a simple name. | Accessed through an index. |
Can be a static or an instance member. | Must be an instance member. |
A get accessor of a property has no parameters. | A get accessor of an indexer has the same formal parameter list as the indexer. |
A set accessor of a property contains the implicit value parameter. | A set accessor of an indexer has the same formal parameter list as the indexer, and also to the value parameter. |
Supports shortened syntax with Auto-Implemented Properties (C# Programming Guide). | Does not support shortened syntax. |
Conclusion
Read more:
- C# and ASP.NET Questions (All in one)
- MVC Interview Questions
- C# and ASP.NET Interview Questions and Answers
- Web Services and Windows Services Interview Questions
Other Series
My other series of articles:
For more informative articles visit my Blog.
7 comments