You can't make a Static Indexer in C#… The CLR can, but you can't with C#.
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.
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With