Multiple index properties on a type?

The only way you could do this would be to have Books be a property that returns a type that has its own suitable indexer. Here's one possible approach:

public class Indexer<TKey, TValue>
{
    private Func<TKey, TValue> func;

    public Indexer(Func<TKey, TValue> func)
    {
        if (func == null)
            throw new ArgumentNullException("func");

        this.func = func;
    }

    public TValue this[TKey key]
    {
        get { return func(key); }
    }
}

class Library
{
    public Indexer<string, Book> Books { get; private set; }
    public Indexer<string, DateTime> PublishingDates { get; private set; }

    public Library()
    {
        Books = new Indexer<string, Book>(GetBookByName);
        PublishingDates = new Indexer<string, DateTime>(GetPublishingDate);
    }

    private Book GetBookByName(string bookName)
    {
        // ...
    }

    private DateTime GetPublishingDate(string bookName)
    {
        return GetBookByName(bookName).PublishingDate;
    }
}

But you should seriously consider providing an implementation of IDictionary<,> instead of using this approach, as it will allow other nifty stuff, like enumeration of key-value pairs, etc.


C# doesn't support it, unfortunately. It only recognises the this[] property, which is really just an indexable property named Item when compiled. The CLI supports any number of indexable properties though, and that can be reflected in some other languages like F#, where you can define your own.

Even when you do define your own in CIL or otherwise though, you still can't call them from C# like you would want to, you need to make a manual call to get_Books(index); for a property named Books. All properties are just syntactic sugar for method calls like that. C# only recognises the property named Item as indexable.


In C#, indexers have to be called this (see http://msdn.microsoft.com/en-us/library/aa664459(v=VS.71).aspx). You can overload indexers, but remember that C# doesn't allow overloading based on return type only. So, whereas you can have:

public int this[int i]
public string this[string s]

You couldn't have:

public int this[int i]
public string this[int i]

The .NET class library design guidelines recommend having only one indexer per class.

So in your case, there's no way to do what you're asking using indexers only.

Tags:

C#

.Net