Warm‑up: Indexers Toolkit (string + int) — with hidden reference answer
Warm‑up (with answer): Build a small settings store that supports: - indexer with string key: store["theme"] - indexer with int key: store[0] (access keys by insertion order) - validation + friendly exceptions - get-only indexer pattern for "read-only view" ✅ Warm-up includes a reference answer (hidden behind a button) that covers indexer syntax and typical patterns.
using System; // Console
using System.Collections.Generic; // Dictionary, List
namespace ItTechGenie.M1.Indexers.WarmUp
{
public class SettingsStore // settings container
{
private readonly Dictionary<string, string> _map = // key/value map
new(StringComparer.OrdinalIgnoreCase); // case-insensitive keys
private readonly List<string> _keys = new(); // insertion order keys
// ✅ Warm-up TODO: Student must implement only this indexer (string key)
public string this[string key] // indexer by key
{
get
{
// TODO:
// - validate key (null/empty/whitespace)
// - if missing, throw KeyNotFoundException with message
// - return stored value
throw new NotImplementedException();
}
set
{
// TODO:
// - validate key
// - add key to _keys if new
// - store in _map
throw new NotImplementedException();
}
}
// ✅ Warm-up TODO: Student must implement only this indexer (int index)
public string this[int index] // indexer by position
{
get
{
// TODO:
// - validate index range
// - map index -> key using _keys
// - return this[key]
throw new NotImplementedException();
}
}
// (Optional pattern) a read-only view for safe sharing
public IReadOnlySettings ReadOnly() => new ReadOnlySettings(this); // wrapper
public sealed class ReadOnlySettings // nested wrapper
{
private readonly SettingsStore _inner; // wrapped store
public ReadOnlySettings(SettingsStore inner) => _inner = inner; // ctor
public string this[string key] => _inner[key]; // get-only indexer
}
}
internal class Program
{
static void Main()
{
var store = new SettingsStore(); // create store
store["theme mode"] = "Dark ✅"; // set via string indexer
store["page-size"] = " 20 "; // set another
Console.WriteLine(store["theme mode"]); // get by key
Console.WriteLine(store[0]); // get by position
var ro = store.ReadOnly(); // get read-only
Console.WriteLine(ro["page-size"]); // read-only access
}
}
}
Warm‑up Reference Answer (Conceptual Steps)
Reference approach (key steps): 1) String indexer: - if (string.IsNullOrWhiteSpace(key)) throw new ArgumentException(...) - if (! _map.TryGetValue(key, out var v)) throw new KeyNotFoundException(...) - return v - in set: if key new => _keys.Add(key); then _map[key]=value ?? "" (or allow null decision) 2) Int indexer: - if (index < 0 || index >= _keys.Count) throw new IndexOutOfRangeException(...) - var key = _keys[index]; return this[key]; 3) Read-only wrapper: - Provide get-only indexer that delegates to inner store to prevent writes.