Skip to main content

How to Resolve Error "CS0668: Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type" in C#

The Compiler Error CS0668 is a configuration error related to Indexers and the IndexerName attribute. The message reads: "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type".

In C#, indexers (defined via this[...]) allow instances of a class to be indexed like arrays. Internally, the compiler translates all indexers into a single Property (usually named Item). If you overload indexers (e.g., one takes an int, another takes a string), they are just overloads of that same property. Therefore, they must share the same internal name. You cannot name one overload "Item" and another overload "Value".

This guide explains how to correctly apply the IndexerName attribute to overloaded indexers.

Understanding Internal Indexer Names

By default, every C# indexer compiles to a property named Item.

  • public int this[int i] $\rightarrow$ public int Item { get(int i); }
  • public int this[string s] $\rightarrow$ public int Item { get(string s); }

The [IndexerName("Name")] attribute allows you to change this internal name (e.g., to Value or Data). However, because a class can only have one "Default Member" (the member mapped to the [] syntax), all indexers in that class must map to that same name.

Scenario: Inconsistent Naming

This error occurs when you apply the IndexerName attribute to one indexer but give a different name (or no name, defaulting to "Item") to another indexer in the same class.

Example of error:

using System.Runtime.CompilerServices;

public class DataCollection
{
private string[] _storage = new string[10];

// 1. First Indexer: Renamed to "MyItem"
[IndexerName("MyItem")]
public string this[int index]
{
get { return _storage[index]; }
set { _storage[index] = value; }
}

// 2. Second Indexer: Renamed to "OtherItem"
// ⛔️ Error CS0668: Two indexers have different names.
// You cannot mix "MyItem" and "OtherItem" in the same class.
[IndexerName("OtherItem")]
public string this[string key]
{
get { return "Value"; }
set { }
}
}
note

Even if you omit the attribute on the second indexer, the error persists because the second one defaults to "Item", which conflicts with "MyItem".

Solution: Unify the IndexerName

You have two choices:

  1. Use the Attribute Consistently: Apply the exact same name to every indexer.
  2. Remove the Attribute: Let the compiler default everything to "Item".

Solution:

using System.Runtime.CompilerServices;

public class DataCollection
{
private string[] _storage = new string[10];

// ✅ Correct: Both indexers map to the internal property "MyItem".

[IndexerName("MyItem")]
public string this[int index]
{
get { return _storage[index]; }
set { _storage[index] = value; }
}

[IndexerName("MyItem")]
public string this[string key]
{
get { return "Value"; } // Simplified logic
set { }
}
}

Conclusion

CS0668 enforces consistency in the underlying IL code structure.

  1. Check Attributes: Look for [IndexerName(...)] on your indexers.
  2. Match Names: Ensure the string argument is identical for every this[...] declaration in the file.
  3. Default Behavior: If you don't specifically need to rename the property for Interop reasons, simply remove the attributes.