静态索引器?

为什么在C#中不允许使用静态索引器? 我看不出为什么他们不应该被允许,而且他们可能是非常有用的。

例如:

static class ConfigurationManager { public object this[string name]{ get{ return ConfigurationManager.getProperty(name); } set { ConfigurationManager.editProperty(name, value); } } /// <summary> /// This will write the value to the property. Will overwrite if the property is already there /// </summary> /// <param name="name">Name of the property</param> /// <param name="value">Value to be wrote (calls ToString)</param> public static void editProperty(string name, object value) { DataSet ds = new DataSet(); FileStream configFile = new FileStream("./config.xml", FileMode.OpenOrCreate); ds.ReadXml(configFile); if (ds.Tables["config"] == null) { ds.Tables.Add("config"); } DataTable config = ds.Tables["config"]; if (config.Rows[0] == null) { config.Rows.Add(config.NewRow()); } if (config.Columns[name] == null) { config.Columns.Add(name); } config.Rows[0][name] = value.ToString(); ds.WriteXml(configFile); configFile.Close(); } public static void addProperty(string name, object value) { ConfigurationManager.editProperty(name, value); } public static object getProperty(string name) { DataSet ds = new DataSet(); FileStream configFile = new FileStream("./config.xml", FileMode.OpenOrCreate); ds.ReadXml(configFile); configFile.Close(); if (ds.Tables["config"] == null) { return null; } DataTable config = ds.Tables["config"]; if (config.Rows[0] == null) { return null; } if (config.Columns[name] == null) { return null; } return config.Rows[0][name]; } } 

上面的代码将从静态索引器中受益匪浅。 但是它不会编译,因为不允许使用静态索引器。 这是为什么?

索引器表示法需要this进行参考。 由于静态方法没有对类的特定实例的引用,因此不能对它们使用它,因此不能在静态方法上使用索引器表示法。

解决您的问题是使用单身模式如下:

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

现在你可以使用索引器符号来调用Utilities.ConfigurationManager["someKey"]

我认为这被认为不是非常有用的。 我认为这也是一个耻辱 – 我倾向于使用的一个例子是Encoding,Encoding.GetEncoding(“foo”)可能是Encoding [“Foo”]。 我不认为这会经常发生,但除了其他任何事情之外,它只是感觉有点不一致,不可用。

我将不得不检查,但我怀疑它已经在IL中可用。

作为解决方法,您可以在单例/静态对象上定义一个实例索引器(比如ConfigurationManager是一个单例,而不是一个静态类):

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

这个关键字指的是类的当前实例。 静态成员函数没有这个指针。 这个关键字可以用来从构造函数,实例方法和实例访问器中访问成员(从msdn中获取)。 由于这引用了类的一个实例,它与静态的性质相冲突,因为静态不与类的实例相关联。

一种解决方法是使用索引器对付一个私人字典,所以你只需要创build一个新的实例,并访问静态部分。

  public class ConfigurationManager { public ConfigurationManager() { // TODO: Complete member initialization } public object this[string keyName] { get { return ConfigurationManagerItems[keyName]; } set { ConfigurationManagerItems[keyName] = value; } } private static Dictionary<string, object> ConfigurationManagerItems = new Dictionary<string, object>(); } 

这允许你跳过整个访问类的成员,只是创build它的一个实例和索引。

  new ConfigurationManager()["ItemName"]