Test in a live environment
Test in production without watermarks.
Works wherever you need it to.
An indexer in C# is a special type of property that makes instances of a class or struct to be accessed using the array access operator []. Indexers can be very useful in creating "smart arrays" or encapsulating data in a simplified syntax. They provide a way to use instances of a class just like you would use arrays, where you can access data via an index. This article will explore how to declare and use C# indexers with practical examples. And we'll also explore the IronPDF library at the end of the article.
An indexer is an instance member using the 'this' keyword in a class or struct, followed by the indexer declaration. You also specify the parameter types and the return type. The general syntax for an indexer instance member looks like this:
public return_type this[parameter_type index]
{
get
{
// code to return data
}
set
{
// set accessor, code to set data
}
}
public return_type this[parameter_type index]
{
get
{
// code to return data
}
set
{
// set accessor, code to set data
}
}
Default Public Property Item(ByVal index As parameter_type) As return_type
Get
' code to return data
End Get
Set(ByVal value As return_type)
' set accessor, code to set data
End Set
End Property
Here, return_type is the value type that the indexer will return such as an integer value, and parameter_type is the type of the index, often an int. The get accessor returns the value at the specified index, and the set block code accessor assigns a value to that index.
We'll examine a basic illustration of implementing an indexer within a C# class. Consider a class Program that encapsulates an array of strings.
class Program
{
private string[] values = new string[5]; // Array with 5 elements
public string this[int index]
{
get
{
return values[index];
}
set
{
values[index] = value;
}
}
}
class Program
{
private string[] values = new string[5]; // Array with 5 elements
public string this[int index]
{
get
{
return values[index];
}
set
{
values[index] = value;
}
}
}
Friend Class Program
Private values(4) As String ' Array with 5 elements
Default Public Property Item(ByVal index As Integer) As String
Get
Return values(index)
End Get
Set(ByVal value As String)
values(index) = value
End Set
End Property
End Class
In the above code:
This means you can create an instance of the Program class and access its values array using the indexer, like this:
class Program
{
static void Main()
{
Program program = new Program();
// Set values using indexer
program[0] = "First";
program[1] = "Second";
// Access values using indexer
Console.WriteLine(program[0]); // Output: First
Console.WriteLine(program[1]); // Output: Second
}
}
class Program
{
static void Main()
{
Program program = new Program();
// Set values using indexer
program[0] = "First";
program[1] = "Second";
// Access values using indexer
Console.WriteLine(program[0]); // Output: First
Console.WriteLine(program[1]); // Output: Second
}
}
Friend Class Program
Shared Sub Main()
Dim program As New Program()
' Set values using indexer
program(0) = "First"
program(1) = "Second"
' Access values using indexer
Console.WriteLine(program(0)) ' Output: First
Console.WriteLine(program(1)) ' Output: Second
End Sub
End Class
In this code, you see that the indexer provides a simple syntax for accessing the values array, similar to how you would access elements in an array.
The get and set accessors inside the indexer are like block code that allows you to retrieve and assign data similarly to how you would with properties. The main difference is that indexers use an index parameter to work with collections of data rather than individual data members.
The get block is responsible for returning the data at the specified index, while the set block assigns data to the specified index. Here’s another example to solidify your understanding:
class StudentRecords
{
private string[] studentNames = new string[3];
public string this[int index]
{
get
{
if (index >= 0 && index < studentNames.Length)
{
return studentNames[index];
}
return "Invalid Index";
}
set
{
if (index >= 0 && index < studentNames.Length)
{
studentNames[index] = value;
}
}
}
public int Length
{
get { return studentNames.Length; }
}
}
class StudentRecords
{
private string[] studentNames = new string[3];
public string this[int index]
{
get
{
if (index >= 0 && index < studentNames.Length)
{
return studentNames[index];
}
return "Invalid Index";
}
set
{
if (index >= 0 && index < studentNames.Length)
{
studentNames[index] = value;
}
}
}
public int Length
{
get { return studentNames.Length; }
}
}
Friend Class StudentRecords
Private studentNames(2) As String
Default Public Property Item(ByVal index As Integer) As String
Get
If index >= 0 AndAlso index < studentNames.Length Then
Return studentNames(index)
End If
Return "Invalid Index"
End Get
Set(ByVal value As String)
If index >= 0 AndAlso index < studentNames.Length Then
studentNames(index) = value
End If
End Set
End Property
Public ReadOnly Property Length() As Integer
Get
Return studentNames.Length
End Get
End Property
End Class
In this example:
You can use this class in the Main method as follows:
class Program
{
public static void Main()
{
StudentRecords records = new StudentRecords();
// Set values using indexer
records[0] = "John";
records[1] = "Jane";
records[2] = "Bob";
// Access values using indexer
for (int i = 0; i < records.Length; i++)
{
Console.WriteLine(records[i]);
}
}
}
class Program
{
public static void Main()
{
StudentRecords records = new StudentRecords();
// Set values using indexer
records[0] = "John";
records[1] = "Jane";
records[2] = "Bob";
// Access values using indexer
for (int i = 0; i < records.Length; i++)
{
Console.WriteLine(records[i]);
}
}
}
Friend Class Program
Public Shared Sub Main()
Dim records As New StudentRecords()
' Set values using indexer
records(0) = "John"
records(1) = "Jane"
records(2) = "Bob"
' Access values using indexer
For i As Integer = 0 To records.Length - 1
Console.WriteLine(records(i))
Next i
End Sub
End Class
You can also create generic classes with indexers, allowing your code to handle multiple data types. Here’s a simple example of a generic class with a generic indexer:
class GenericClass<T>
{
private T[] elements = new T[5];
public T this[int index]
{
get
{
return elements[index];
}
set
{
elements[index] = value;
}
}
public int Length
{
get { return elements.Length; }
}
}
class GenericClass<T>
{
private T[] elements = new T[5];
public T this[int index]
{
get
{
return elements[index];
}
set
{
elements[index] = value;
}
}
public int Length
{
get { return elements.Length; }
}
}
Friend Class GenericClass(Of T)
Private elements(4) As T
Default Public Property Item(ByVal index As Integer) As T
Get
Return elements(index)
End Get
Set(ByVal value As T)
elements(index) = value
End Set
End Property
Public ReadOnly Property Length() As Integer
Get
Return elements.Length
End Get
End Property
End Class
In this code:
You can now use the GenericClass with different data types in the Main method:
class Program
{
public static void Main()
{
GenericClass<int> intArray = new GenericClass<int>();
intArray[0] = 10;
intArray[1] = 20;
GenericClass<string> stringArray = new GenericClass<string>();
stringArray[0] = "Hello";
stringArray[1] = "World";
// Output the integer array values
for (int i = 0; i < intArray.Length; i++)
{
Console.WriteLine(intArray[i]);
}
// Output the string array values
for (int i = 0; i < stringArray.Length; i++)
{
Console.WriteLine(stringArray[i]);
}
}
}
class Program
{
public static void Main()
{
GenericClass<int> intArray = new GenericClass<int>();
intArray[0] = 10;
intArray[1] = 20;
GenericClass<string> stringArray = new GenericClass<string>();
stringArray[0] = "Hello";
stringArray[1] = "World";
// Output the integer array values
for (int i = 0; i < intArray.Length; i++)
{
Console.WriteLine(intArray[i]);
}
// Output the string array values
for (int i = 0; i < stringArray.Length; i++)
{
Console.WriteLine(stringArray[i]);
}
}
}
Friend Class Program
Public Shared Sub Main()
Dim intArray As New GenericClass(Of Integer)()
intArray(0) = 10
intArray(1) = 20
Dim stringArray As New GenericClass(Of String)()
stringArray(0) = "Hello"
stringArray(1) = "World"
' Output the integer array values
For i As Integer = 0 To intArray.Length - 1
Console.WriteLine(intArray(i))
Next i
' Output the string array values
For i As Integer = 0 To stringArray.Length - 1
Console.WriteLine(stringArray(i))
Next i
End Sub
End Class
IronPDF is a C# library designed for generating, editing, and converting PDFs in .NET applications. It simplifies working with PDFs for developers to create PDFs from HTML, manipulate PDF files, and handle advanced functionalities such as merging, printing, and adding signatures programmatically.
You can leverage IronPDF within your C# programs that utilize indexers to dynamically generate and manage PDF content. For example, suppose you have a class that holds HTML strings, and you want to generate PDFs for each HTML entry using an indexer. This approach streamlines PDF generation while keeping your code organized and intuitive.
using IronPdf;
using System;
class PdfGenerator
{
private string[] htmlTemplates = new string[3];
public string this[int index]
{
get { return htmlTemplates[index]; }
set { htmlTemplates[index] = value; }
}
public void GeneratePdf(int index, string outputPath)
{
var renderer = new ChromePdfRenderer();
var pdfDocument = renderer.RenderHtmlAsPdf(this[index]); // Access HTML string using indexer
pdfDocument.SaveAs(outputPath);
}
}
class Program
{
public static void Main()
{
PdfGenerator pdfGen = new PdfGenerator();
// Populate HTML templates
pdfGen[0] = "<h1>First Document</h1><p>This is the first PDF.</p>";
pdfGen[1] = "<h1>Second Document</h1><p>This is the second PDF.</p>";
pdfGen[2] = "<h1>Third Document</h1><p>This is the third PDF.</p>";
// Generate PDFs using the indexer
pdfGen.GeneratePdf(0, "first.pdf");
pdfGen.GeneratePdf(1, "second.pdf");
pdfGen.GeneratePdf(2, "third.pdf");
Console.WriteLine("PDFs generated successfully.");
}
}
using IronPdf;
using System;
class PdfGenerator
{
private string[] htmlTemplates = new string[3];
public string this[int index]
{
get { return htmlTemplates[index]; }
set { htmlTemplates[index] = value; }
}
public void GeneratePdf(int index, string outputPath)
{
var renderer = new ChromePdfRenderer();
var pdfDocument = renderer.RenderHtmlAsPdf(this[index]); // Access HTML string using indexer
pdfDocument.SaveAs(outputPath);
}
}
class Program
{
public static void Main()
{
PdfGenerator pdfGen = new PdfGenerator();
// Populate HTML templates
pdfGen[0] = "<h1>First Document</h1><p>This is the first PDF.</p>";
pdfGen[1] = "<h1>Second Document</h1><p>This is the second PDF.</p>";
pdfGen[2] = "<h1>Third Document</h1><p>This is the third PDF.</p>";
// Generate PDFs using the indexer
pdfGen.GeneratePdf(0, "first.pdf");
pdfGen.GeneratePdf(1, "second.pdf");
pdfGen.GeneratePdf(2, "third.pdf");
Console.WriteLine("PDFs generated successfully.");
}
}
Imports IronPdf
Imports System
Friend Class PdfGenerator
Private htmlTemplates(2) As String
Default Public Property Item(ByVal index As Integer) As String
Get
Return htmlTemplates(index)
End Get
Set(ByVal value As String)
htmlTemplates(index) = value
End Set
End Property
Public Sub GeneratePdf(ByVal index As Integer, ByVal outputPath As String)
Dim renderer = New ChromePdfRenderer()
Dim pdfDocument = renderer.RenderHtmlAsPdf(Me(index)) ' Access HTML string using indexer
pdfDocument.SaveAs(outputPath)
End Sub
End Class
Friend Class Program
Public Shared Sub Main()
Dim pdfGen As New PdfGenerator()
' Populate HTML templates
pdfGen(0) = "<h1>First Document</h1><p>This is the first PDF.</p>"
pdfGen(1) = "<h1>Second Document</h1><p>This is the second PDF.</p>"
pdfGen(2) = "<h1>Third Document</h1><p>This is the third PDF.</p>"
' Generate PDFs using the indexer
pdfGen.GeneratePdf(0, "first.pdf")
pdfGen.GeneratePdf(1, "second.pdf")
pdfGen.GeneratePdf(2, "third.pdf")
Console.WriteLine("PDFs generated successfully.")
End Sub
End Class
C# indexers are a useful feature that helps you to make your classes and structs behave like arrays. By providing simplified syntax and flexible data access, you can create more intuitive and readable code. Whether you’re working with strings, integers, or any other data type, indexers give you the ability to encapsulate your data structure and access it using indices cleanly and efficiently.
IronPDF makes it easy to get started with a free trial that gives you access to all the features you need to create, manipulate, and render PDFs. You can take your time exploring the software, and once you're satisfied, licenses are available starting at $749.
9 .NET API products for your office documents