Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Static Indexers?

People also ask

Can we have static indexer in C#?

You can't make a Static Indexer in C#… The CLR can, but you can't with C#.

What are indexers used for?

Indexers are a syntactic convenience that enable you to create a class, struct, or interface that client applications can access as an array. The compiler will generate an Item property (or an alternatively named property if IndexerNameAttribute is present), and the appropriate accessor methods.

What is indexer with example?

Indexers allow instances of a class or struct to be indexed just like arrays. The indexed value can be set or retrieved without explicitly specifying a type or instance member. Indexers resemble properties except that their accessors take parameters.


I believe it was considered not to be terribly useful. I think it's a shame too - an example I tend to use is Encoding, where Encoding.GetEncoding("foo") could be Encoding["Foo"]. I don't think it would come up very often, but aside from anything else it just feels a little inconsistent not to be available.

I would have to check, but I suspect it's available in IL (Intermediate Language) already.


Indexer notation requires a reference to this. Since static methods don't have a reference to any particular instance of the class, you can't use this with them, and consequently you can't use indexer notation on static methods.

The solution to your problem is using a singleton pattern as follows:

public class Utilities
{
    private static ConfigurationManager _configurationManager = new ConfigurationManager();
    public static ConfigurationManager ConfigurationManager => _configurationManager;
}

public class ConfigurationManager
{
    public object this[string value]
    {
        get => new object();
        set => // set something
    }
}

Now you can call Utilities.ConfigurationManager["someKey"] using indexer notation.


As a work-around, you can define an instance indexer on a singleton/static object (say that ConfigurationManager is a singleton, instead of being a static class):

class ConfigurationManager
{
  //private constructor
  ConfigurationManager() {}
  //singleton instance
  public static ConfigurationManager singleton;
  //indexer
  object this[string name] { ... etc ... }
}

I was also in need (well, more like nice-to-have) of an static indexer to store attributes, so I figured out a somewhat awkward workaround:

Within the class you want to have an static indexer (here: Element), create a subclass of the same name + "Dict". Give it a readonly static as instance of said subclass, and then add your desired indexer.

Last, add the class as static import (hence the subclass to only expose the static field).

import static Element.ElementDict;

public class Element {
    // .... 
    private static readonly Dictionary<string, object> elemDict = new Dictionary<string, object>();
    public class ElementDict {
        public readonly static ElementDict element = new ElementDict();
        public object this[string key] {
            get => elemDict.TryGetValue(key, out object o) ? o : null;
            set => elemDict[key] = value;
        }
    }
}

and then you can use it either capitalized as Type, or without as dictionary:

var cnt = element["counter"] as int;
element["counter"] = cnt;

But alas, if one were to actually use object as "value"-Type, then the below would be still shorter (at least as declaration), and also provide immediate Typecasting:

public static T load<T>(string key) => elemDict.TryGetValue(key, out object o) ? (T) o : default(T);
public static void store<T>(string key, T value) => elemDict[key] = value;

var cnt = Element.load<int>("counter");
Element.store("counter", cnt);