0

In the docs for C# Indexers, it states:

Indexers are a syntactic convenience that enable you to create a class, struct, or interface that client applications can access just as an array. Indexers are most frequently implemented in types whose primary purpose is to encapsulate an internal collection or array.

I have only ever seen them associated with this single use case.
What are the other apparent use cases?

Zze
  • 18,229
  • 13
  • 85
  • 118
  • https://stackoverflow.com/questions/3315213/when-should-you-use-c-sharp-indexers – ilansch Mar 09 '18 at 06:13
  • @ilansch Yes, that is the single use case that the quote references, what are the other ones? Because the it states it is the most frequent so obviously there are more than 1? – Zze Mar 09 '18 at 06:15
  • I cant think of an example where an indexer was used by MS and it didn't have something to do with a collection or array or list of some sort. Though i have abused them once or twice – TheGeneral Mar 09 '18 at 06:18
  • You may or not may return different types (e.g. `float this` or `double this`), return an index of an enum or calculate something in dependency of your `index`... – Essigwurst Mar 09 '18 at 06:25
  • Also, see: https://stackoverflow.com/questions/2185071/real-world-use-cases-for-c-sharp-indexers – Essigwurst Mar 09 '18 at 07:19

2 Answers2

2

You can get a complete list of indexed properties, and the names of the keys that are used to index them, with code like this:

var list = System.AppDomain.CurrentDomain.GetAssemblies()
    .SelectMany
    (
        a => a.GetTypes().SelectMany
        (
            t => t.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)
            .Where
            (
                p => p.GetIndexParameters().Length > 0
            )
            .Select
            (
                prop => string.Format
                (
                    "{0}.{1}[{2}]",
                    t.FullName,
                    prop.Name,
                    string.Join
                    (
                        ",",
                        prop.GetIndexParameters().Select(ip => ip.Name)
                    )
                )
            )
        )
    );

If you look through the list, you'll see the vast, vast majority have an indexed parameter named "index" or "key." So it seems that is indeed the majority use case.

In some pretty rare cases you'll see some alternative uses. For example, there is a private class within XmlToDataSetMap (source) that accepts a several alternative "keys" (an XmlDataReader, for example, or a DataTable) which do not act as a key but do serve to populate a key (e.g. by copying some properties into a different object which is then used as an indexer key). But the property is still named Item[] and the overall concept is one of containing a collection, and indeed, the class inherits from HashTable.

(On a side note, XmlToDataSetMap also contains another private class , XmlNodeIdentety, whose name contains the only blatant misspelling I've ever seen in the CLR. So maybe we don't want to follow the example of whoever wrote this class.)

John Wu
  • 50,556
  • 8
  • 44
  • 80
-1

Theoretically you can do everything with indexers you can also do with functions. But as indexers 'optically simulate' arrays it would be bad style to use them for something what is not 'array-like'.

I think the focus is on 'internal collection'. Imagine (as very bad example) an array with square numbers (e.g. a[0]=0; a[1]=1; a[2]=4;). You can also reach the same 'array' by indexers without holding any internal collection.

Although this case is very stupid there may be more reasonable cases.

For example if it is not clear previously if it is better to preallocate an array for performance reasons or to calculate the array elements dynamically. Here you could get both behaviours with the same syntax.

Fratyx
  • 5,717
  • 1
  • 12
  • 22