What if you could access your custom objects as easily as array items, but with your own special keys?
Why Indexer with custom types in C Sharp (C#)? - Purpose & Use Cases
Imagine you have a collection of custom objects, like books or products, and you want to access them quickly using a special key, such as a unique ID or a combination of properties.
Without indexers, you would have to write long methods to search through the collection every time you want to find an item.
Manually searching through collections is slow and repetitive. You might write similar code again and again, increasing the chance of mistakes.
It also makes your code messy and hard to read, especially when you want to access items like they were in an array.
Using an indexer with custom types lets you access your objects using a simple, array-like syntax but with your own keys.
This makes your code cleaner, faster to write, and easier to understand, because you can use meaningful keys instead of just numbers.
public Book GetBookByISBN(string isbn) { foreach(var book in books) { if(book.ISBN == isbn) return book; } return null; }public Book this[string isbn] { get { return books.FirstOrDefault(b => b.ISBN == isbn); } }You can access complex collections quickly and clearly using custom keys, just like using an array.
Think of a library system where you want to get a book by its ISBN code directly, instead of searching through all books manually every time.
Manual searching is slow and error-prone.
Indexers let you use custom keys to access data easily.
This makes your code cleaner and more intuitive.
Practice
What is the main purpose of an indexer in a C# class?
Choose the best description.
Solution
Step 1: Understand what an indexer does
An indexer lets you use square brackets [] to access elements inside an object, similar to arrays.Step 2: Identify the correct description
Only To allow objects to be accessed using array-like bracket syntax with custom keys. describes this behavior correctly by mentioning bracket syntax and custom keys.Final Answer:
To allow objects to be accessed using array-like bracket syntax with custom keys. -> Option CQuick Check:
Indexer = bracket access [OK]
- Confusing indexers with constructors
- Thinking indexers define collection size
- Mixing indexers with operator overloading
Which of the following is the correct syntax to declare an indexer in a C# class using a custom type Key as the index?
public class MyCollection {
// Indexer declaration here
}Solution
Step 1: Recall indexer syntax
Indexers use the keywordthisfollowed by square brackets with the parameter type and name inside.Step 2: Check each option
public string this[Key key] { get; set; } correctly usesthis[Key key]with get and set accessors. Others have syntax errors or wrong brackets.Final Answer:
public string this[Key key] { get; set; } -> Option AQuick Check:
Indexer syntax = this[Type name] { get; set; } [OK]
- Using parentheses instead of brackets
- Omitting parameter name in brackets
- Using expression-bodied syntax incorrectly
Given the following code, what will be the output?
public record Key(int Id);
public class Store {
private Dictionary<Key, string> data = new();
public string this[Key key] {
get => data.TryGetValue(key, out var val) ? val : "Not found";
set => data[key] = value;
}
}
var store = new Store();
store[new Key(1)] = "Apple";
store[new Key(2)] = "Banana";
Console.WriteLine(store[new Key(1)]);
Console.WriteLine(store[new Key(3)]);Solution
Step 1: Understand how the indexer accesses data
The indexer uses a Dictionary with Key as key type. It returns the value if found, else "Not found".Step 2: Check the keys used
Keys with Id 1 and 2 are added. Accessing new Key(1) finds "Apple". Accessing new Key(3) is missing, so returns "Not found".Final Answer:
Apple Not found -> Option DQuick Check:
Key(1) found, Key(3) missing = Apple, Not found [OK]
- Assuming new Key(1) is different from stored Key(1)
- Expecting Banana for Key(3)
- Ignoring TryGetValue fallback
Identify the error in the following code snippet that implements an indexer with a custom type Key:
public class DataStore {
private Dictionary<Key, int> dict = new();
public int this[Key key] {
get { return dict[key]; }
set { dict.Add(key, value); }
}
}Solution
Step 1: Analyze the set accessor
The set accessor uses dict.Add(key, value), which throws an exception if the key already exists.Step 2: Suggest correct usage
To update or add, use dict[key] = value; which overwrites existing or adds new key.Final Answer:
Using dict.Add in set causes exception if key exists; should use dict[key] = value. -> Option AQuick Check:
dict.Add throws if key exists; use dict[key] = value [OK]
- Using Add instead of index assignment in set
- Thinking Key cannot be indexer parameter
- Confusing return types in indexer
You want to create a class Matrix that uses a custom struct Position as the indexer key to store integer values. The Position struct has two int fields: Row and Col. Which approach correctly implements the indexer to allow getting and setting values by Position?
public struct Position {
public int Row, Col;
public Position(int r, int c) { Row = r; Col = c; }
}
public class Matrix {
private Dictionary<Position, int> values = new();
// Implement indexer here
}Solution
Step 1: Consider safe get behavior
Using TryGetValue with fallback 0 avoids exceptions if the position key is missing.Step 2: Check set accessor correctness
Using values[pos] = value; safely adds or updates the dictionary entry.Step 3: Evaluate other options
public int this[int row, int col] { get => values[new Position(row, col)]; set => values[new Position(row, col)] = value; } uses two parameters, not matching the question's single Position key. public int this[Position pos] { get { return values[pos]; } set { values.Add(pos, value); } } uses Add in set, which throws if key exists. public int this[Position pos] { get => values[pos]; set => values[pos] = value; }'s get accessor throws if key missing.Final Answer:
public int this[Position pos] { get => values.TryGetValue(pos, out var v) ? v : 0; set => values[pos] = value; } -> Option BQuick Check:
Safe get with TryGetValue + index assignment set [OK]
- Using Add in set causing exceptions
- Not handling missing keys in get
- Using multiple parameters instead of custom type
Ready to prove it?
Pass the test and this pattern moves unknown
