Custom Indexers: Ruby vs C#

In C#, I can make a custom indexer. In other words, I can write my own class that will let me say things like var x = myClass[foo]; and have my own code run when we “index” into myClass with foo. In Ruby, I was wondering how to do this. I knew that I could subtype Array or Hash and get something like this, but (1) that might not be best practice, and (2) I want to know whether [] and []= are built into the language, or I can define their behavior myself. As is often the case with Ruby, this feature is wide open and I can override or modify this behavior. In order to illustrate this, I decided to make a case insensitive dictionary in both Ruby and C#. This dictionary will use strings as its keys, and will return the value associated with a string in any casing. (Note that this is not a dictionary I have a real use case for; I am just building it as an experiment.)

Here’s the Ruby implementation of this class (note that I change string keys to lower case then to symbols):

class CaseInsensitiveHash
def initialize
@hsh = {}
def get(key)
raise ArgumentError unless key.respond_to?(:to_s)
def set(key, value)
raise ArgumentError unless key.respond_to?(:to_s)
actual_key = key.to_s.downcase.to_sym
@hsh[actual_key] = value
alias [] get
alias []= set

Lines 17 and 18 are where the magic happens. Just by aliasing [] and []= to methods that I wrote, I can make a collection that looks like an array.

I can write things like:

hsh =
hsh['foo'] = 'some value'
assert_equal hsh['FOO'], 'some value'

I was surprised how easy this was.

Accomplishing the same thing in C# is also pretty simple:

using System;
using System.Collections.Generic;
namespace collections
public class CaseInsensitiveDictionary<T>
private Dictionary<String, T> _dict;
public CaseInsensitiveDictionary()
_dict = new Dictionary<String, T>();
public void Set(string key, T value)
string actualKey = key.ToLower();
_dict[actualKey] = value;
public T Get(string key)
string actualKey = key.ToLower();
return _dict[actualKey];
public T this[string key]
get { return Get(key); }
set { Set(key, value); }

Note that I could have written Get and Set methods inside the body of the get{} and set{} blocks on lines 28 and 29, but I thought that the analogy to the Ruby code would be cleaner if I structured the classes more similarly. The big difference now is that Ruby is worried about the type of the arguments, (hence the repond_to? checks), and has symbols, which don’t really have an analog in C#, but are the standard type to use as hash keys.

So anyway, there’s a language feature you know how to use in C# and in Ruby! Till next week, happy learning!


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s