How to Resolve Error "CS0021: Cannot apply indexing with [] to an expression of type 'type'" in C#
The Compiler Error CS0021 indicates a misuse of the square bracket [] syntax. For example, the message states: "Cannot apply indexing with [] to an expression of type 'DataType'".
In C#, square brackets are used for Indexers. This syntax allows you to access elements in a collection (like an array, List<T>, or Dictionary<K,V>) by their position or key. This error occurs when you try to use this syntax on a variable type that does not support direct indexing, such as a simple scalar value (like an int) or a collection interface that doesn't guarantee random access (like IEnumerable<T>).
This guide covers the common scenarios where this error appears and how to fix them.
Understanding Indexers
To use myVariable[0], myVariable must be a type that explicitly supports it.
- Supported: Arrays (
int[]), Lists (List<int>), Dictionaries (Dictionary<int, string>), and classes with a definedthis[]property. - Not Supported: Single values (
int,DateTime), generic enumerables (IEnumerable<T>), and objects without an indexer definition.
Scenario 1: Indexing Scalar Values
The most basic cause is attempting to treat a single value as if it were a list.
Example of Mistake
public void ProcessNumber()
{
int number = 500;
// ⛔️ Error CS0021: Cannot apply indexing with [] to an expression of type 'int'
// An integer is just one number; it has no "index 0".
int digit = number[0];
}
Solution
If you meant to create an array, change the declaration. If you meant to access the variable itself, remove the brackets.
public void ProcessNumber()
{
// ✅ Correct: Declare it as an array if you want multiple items
int[] numbers = { 500, 600 };
int digit = numbers[0];
System.Console.WriteLine(digit);
}
// Output: 500
Scenario 2: The IEnumerable<T> Trap
This is the most common real-world occurrence. IEnumerable<T> is the base interface for collections in .NET. It allows you to iterate (foreach), but it does not guarantee that the underlying data allows direct access by index.
Even if the underlying object is an Array or List, if the variable is defined as IEnumerable<T>, the compiler only allows IEnumerable operations.
Example of Mistake
using System.Collections.Generic;
public class DataProcessor
{
public void ProcessList(IEnumerable<string> names)
{
// ⛔️ Error CS0021: 'names' is an IEnumerable, which doesn't support [0]
string firstName = names[0];
}
}
Solution 1: Use LINQ ElementAt()
If you need to get an item by index from an IEnumerable, use the LINQ extension method.
using System.Linq; // Required for ElementAt
using System.Collections.Generic;
public void ProcessList(IEnumerable<string> names)
{
// ✅ Correct: LINQ handles the retrieval
string firstName = names.ElementAt(0);
}
ElementAt(i) can be slow (O(N) complexity) because it might have to loop through the list to find the item. Standard indexing [i] on an Array/List is instant (O(1)).
Solution 2: Convert to List or Array
If you need frequent index access, convert the collection to a type that supports it.
using System.Linq;
using System.Collections.Generic;
public void ProcessList(IEnumerable<string> names)
{
// ✅ Correct: Convert to List, which supports [i]
List<string> nameList = names.ToList();
string firstName = nameList[0];
}
Scenario 3: Adding Indexers to Custom Classes
If you have created your own class (e.g., a Team class containing a list of Player objects) and you want to access players using syntax like myTeam[0], you must define an Indexer.
Example of Mistake
public class Team
{
private string[] _players = { "Alice", "Bob", "Charlie" };
}
class Program
{
static void Main()
{
Team myTeam = new Team();
// ⛔️ Error CS0021: The class 'Team' has no indexer defined
string player = myTeam[0];
}
}
Solution: Define this[int index]
You can make your class behave like an array by adding a special property named this.
public class Team
{
private string[] _players = { "Alice", "Bob", "Charlie" };
// ✅ Correct: Define the Indexer
public string this[int i]
{
get { return _players[i]; }
set { _players[i] = value; }
}
}
class Program
{
static void Main()
{
Team myTeam = new Team();
// Now this works!
string player = myTeam[0];
System.Console.WriteLine(player);
}
}
// Output: Alice
Conclusion
CS0021 means "You are using brackets [] on something that isn't a list".
- Check the Type: Hover over the variable. Is it an
int,DateTime, orObject? These don't support indexing. - Check for IEnumerable: If the variable is
IEnumerable<T>, use.ElementAt(i)or.ToList()instead of[i]. - Check Custom Classes: If it's your own class, you must explicitly implement an indexer (
public T this[int i]) to enable this syntax.