Multiple index properties for a type?

Is it possible to have something like this in C #? I'm not very sure:

class Library { public string Books[string title] { get{return this.GetBookByName(string title);} } public DateTime PublishingDates[string title] { get{return this.GetBookByName(string title).PublishingDate;} } } 

Therefore, it can be used as such:

 myLibrary.Books["V For Vendetta"] myLibrary.PublishingDates["V For Vendetta"] = ... 

So, my full member methods that I need to implement in my structure (by calling them):

 GetCustomStringValue (key) GetCustomIntValue (key) GetCustomBoolValue (key) GetCustomFloatValue (key) SetCustomStringValue (key) SetCustomIntValue (key) SetCustomBoolValue (key) SetCustomFloatValue (key) 

I want to use them cleaner in my own type.

+7
source share
4 answers

The only way you could do this would be to have the Books property, which returns a type that has its own suitable index. Here is 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 this will allow you to use other great things, such as enumerating key-value pairs, etc.

+11
source

In C #, indexers should be called this (see http://msdn.microsoft.com/en-us/library/aa664459(v=VS.71).aspx ). You can overload indexers, but remember that C # does not allow overloading only based on the return type. So, while you can:

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

You could not have:

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

Recommendations for developing a .NET class library recommend that you have only one index for each class.

So, in your case there is no way to do what you ask, using only indexers.

+2
source

C #, unfortunately, does not support it. It recognizes the this[] property, which is actually only an indexable property called Item at compile time. The CLI supports any number of indexable properties, and this may be reflected in some other languages, such as F #, where you can define your own.

Even when you define your own in CIL or otherwise, you still cannot call them from C # as you would like, you need to make a manual call get_Books(index); for a property named Books . All properties are just syntactic sugar for such method calls. C # recognizes a property called Item as indexable.

+1
source

Why not just use the methods?

 class Library { public string Books(string title) { return this.GetBookByName(title); } public DateTime PublishingDates(string title) { return this.GetBookByName(title).PublishingDate; } } 
0
source

All Articles