
- C# - Home
- C# - Overview
- C# - Environment
- C# - Program Structure
- C# - Basic Syntax
- C# - Data Types
- C# - Type Conversion
- C# - Variables
- C# - Constants
- C# - Operators
- C# - Arithmetic Operators
- C# - Assignment Operators
- C# - Relational Operators
- C# - Logical Operators
- C# - Bitwise Operators
- C# - Miscellaneous Operators
- C# - Operators Precedence
- C# Conditional Statements
- C# - Decision Making
- C# - If
- C# - If Else
- C# - Nested If
- C# - Switch
- C# - Nested Switch
- C# Control Statements
- C# - Loops
- C# - For Loop
- C# - While Loop
- C# - Do While Loop
- C# - Nested Loops
- C# - Break
- C# - Continue
- C# OOP & Data Handling
- C# - Encapsulation
- C# - Methods
- C# - Nullables
- C# - Arrays
- C# - Strings
- C# - Structure
- C# - Enums
- C# - Classes
- C# - Inheritance
- C# - Polymorphism
- C# - Operator Overloading
- C# - Interfaces
- C# - Namespaces
- C# - Preprocessor Directives
- C# - Regular Expressions
- C# - Exception Handling
- C# - File I/O
- C# Advanced Tutorial
- C# - Attributes
- C# - Reflection
- C# - Properties
- C# - Indexers
- C# - Delegates
- C# - Events
- C# - Collections
- C# - Generics
- C# - Anonymous Methods
- C# - Unsafe Codes
- C# - Multithreading
C# - Indexers
An indexer allows an object to be indexed such as an array. When you define an indexer for a class, this class behaves similar to a virtual array. You can then access the instance of this class using the array access operator ([ ]).
Syntax
Following is the sytnax of the one-dimensional indexer −
element-type this[int index] { // The get accessor. get { // return the value specified by index } // The set accessor. set { // set the value specified by index } }
Use of Indexers
Declaration of behaviour of an indexer is to some extent similar to a property. similar to the properties, you use get and set accessors for defining an indexer. However, properties return or set a specific data member, whereas indexers returns or sets a particular value from the object instance. In other words, it breaks the instance data into smaller parts and indexes each part, gets or sets each part.
Defining a property involves providing a property name. Indexers are not defined with names, but with the this keyword, which refers to the object instance.
Example
Here, in this example, we demonstrate indexers, allowing objects of the IndexedNames class to be accessed like an array for storing and retrieving names −
using System namespace IndexerApplication { class IndexedNames { private string[] namelist = new string[size]; static public int size = 10; public IndexedNames() { for (int i = 0; i < size; i++) namelist[i] = "N. A."; } public string this[int index] { get { string tmp; if( index >= 0 && index <= size-1 ) { tmp = namelist[index]; } else { tmp = ""; } return ( tmp ); } set { if( index >= 0 && index <= size-1 ) { namelist[index] = value; } } } static void Main(string[] args) { IndexedNames names = new IndexedNames(); names[0] = "Zara"; names[1] = "Riz"; names[2] = "Nuha"; names[3] = "Asif"; names[4] = "Davinder"; names[5] = "Sunil"; names[6] = "Rubic"; for ( int i = 0; i < IndexedNames.size; i++ ) { Console.WriteLine(names[i]); } Console.ReadKey(); } } }
When the above code is compiled and executed, it produces the following result −
Zara Riz Nuha Asif Davinder Sunil Rubic N. A. N. A. N. A.
Defining an Indexer
You can define an indexer by using the "this" keyword followed by a parameter list inside square brackets. Please note that - the indexer must include both get and/or set accessors to retrieve or assign values.
Example
In the following example, we define an indexer to store and retrieve integer values in an internal array using array syntax −
using System; class SampleCollection { private int[] arr = new int[5]; public int this[int index] { get { return arr[index]; } set { arr[index] = value; } } } class Program { static void Main() { SampleCollection sc = new SampleCollection(); sc[0] = 10; sc[1] = 20; Console.WriteLine("Value at index 0: " + sc[0]); Console.WriteLine("Value at index 1: " + sc[1]); } }
When the above code is compiled and executed, it produces the following result −
Value at index 0: 10 Value at index 1: 20
Indexer with String Key (Dictionary-style)
You can define indexers just like dictionaries where strings can be used as keys. This type of definition is useful when you want to retrieve or assign values using a string identifier.
Example
In the following example, we use a string indexer to access and store values in a dictionary-like structure −
using System; using System.Collections.Generic; class Contacts { private Dictionary<string, string> phoneBook = new Dictionary<string, string>(); public string this[string name] { get { return phoneBook.ContainsKey(name) ? phoneBook[name] : "Not Found"; } set { phoneBook[name] = value; } } } class Program { static void Main() { Contacts c = new Contacts(); c["Aman"] = "1234567890"; c["Ravi"] = "9876543210"; Console.WriteLine("Aman's Number: " + c["Aman"]); Console.WriteLine("Ravi's Number: " + c["Ravi"]); Console.WriteLine("Unknown: " + c["Unknown"]); } }
When the above code is compiled and executed, it produces the following result −
Aman's Number: 1234567890 Ravi's Number: 9876543210 Unknown: Not Found
Indexers with Access Modifiers
You can also specify different access levels for the get and set accessors of an indexer using access modifiers.
Example
In the following example, the set accessor is private, so the indexer value can only be set within the class −
using System; class MyCollection { private string[] items = new string[3] { "One", "Two", "Three" }; public string this[int index] { get { return items[index]; } private set { items[index] = value; } } public void UpdateItem(int index, string newValue) { this[index] = newValue; } } class Program { static void Main() { MyCollection col = new MyCollection(); Console.WriteLine("Before: " + col[1]); col.UpdateItem(1, "Updated"); Console.WriteLine("After: " + col[1]); } }
When the above code is compiled and executed, it produces the following result −
Before: Two After: Updated
Overloaded Indexers
Indexers can be overloaded. Indexers can also be declared with multiple parameters and each parameter may be a different type. It is not necessary that the indexes have to be integers. C# allows indexes to be of other types, for example, a string.
Example
This is another example of the indexer. Here, we demonstrate overloaded indexers −
using System; namespace IndexerApplication { class IndexedNames { private string[] namelist = new string[size]; static public int size = 10; public IndexedNames() { for (int i = 0; i < size; i++) { namelist[i] = "N. A."; } } public string this[int index] { get { string tmp; if( index >= 0 && index <= size-1 ) { tmp = namelist[index]; } else { tmp = ""; } return ( tmp ); } set { if( index >= 0 && index <= size-1 ) { namelist[index] = value; } } } public int this[string name] { get { int index = 0; while(index < size) { if (namelist[index] == name) { return index; } index++; } return index; } } static void Main(string[] args) { IndexedNames names = new IndexedNames(); names[0] = "Zara"; names[1] = "Riz"; names[2] = "Nuha"; names[3] = "Asif"; names[4] = "Davinder"; names[5] = "Sunil"; names[6] = "Rubic"; //using the first indexer with int parameter for (int i = 0; i < IndexedNames.size; i++) { Console.WriteLine(names[i]); } //using the second indexer with the string parameter Console.WriteLine(names["Nuha"]); Console.ReadKey(); } } }
When the above code is compiled and executed, it produces the following result −
Zara Riz Nuha Asif Davinder Sunil Rubic N. A. N. A. N. A. 2