If your have a type that represents a collection of values, adding a custom indexer gives you a natural way to index directly into the object using the .[ ] operator.
By adding a custom indexer here I’m now able to write code like this:
Also, as you may have noticed already, F# allows you to use non-integer parameters in your indexer! In this case, I’m using a tuple of int * string * int. You can use this indexer from your C# code too:
That’s pretty cool, but we can go a step further by allowing you to use slicers on our types too. To allow users to get all the notes associated with a range of years, e.g. from 1999 to 2009, let’s add a slicer:
So now we can do this:
Pretty awesome, right? But what if we want to refine our search criteria even more and let you specify a year range as well a range of months, e.g. get me all notes for April/May/June in the years 1999 to 2009. Thankfully, F# lets you define a two-dimensional slicer too:
This two-dimensional slicer allows me to query the calendar with a year range as well as a month range:
As you can see, indexers and slicers give the consumers of your code a much more intuitive way to interact with the data encapsulated in your type. Keep in mind though, that F# does not allow you to add slicer with more than two dimensions, but I think two-dimensional slicers should be good enough for most day-to-day requirements.
Swapped out my verbose optional argument handling with defaultArg as Arseny Kapoulkine pointed out in the comments.