静态索引器?

Mal*_*ist 114 .net c# static indexer static-indexers

为什么C#中不允许使用静态索引器?我认为没有理由不允许他们这样做,而且他们可能非常有用.

例如:

public static class ConfigurationManager 
{
        public object this[string name]
        {
            get => 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) 
        {
            var ds = new DataSet();
            var configFile = new FileStream("./config.xml", FileMode.OpenOrCreate);
            ds.ReadXml(configFile);

            if (ds.Tables["config"] == null)
                ds.Tables.Add("config");

            var 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) 
        {
            var ds = new DataSet();
            var configFile = new FileStream("./config.xml", FileMode.OpenOrCreate);
            ds.ReadXml(configFile);
            configFile.Close();

            if (ds.Tables["config"] == null) return null;

            var config = ds.Tables["config"];

            if (config.Rows[0] == null) return null;
            if (config.Columns[name] == null) return null;

            return config.Rows[0][name];
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

Jon*_*eet 88

我认为它被认为不是非常有用.我认为这也是一种耻辱 - 我倾向于使用的一个例子是编码,Encoding.GetEncoding("foo")可能在哪里Encoding["Foo"].我不认为这会拿出十分频繁,但除了别的它只是感觉有点不一致并不可用.

我必须检查,但我怀疑它已经在IL(中级语言)中可用.

  • 我带来的是我有一个自定义类,它通过静态属性公开我的应用程序中使用的常用值字典.我希望使用静态索引器来缩短从GlobalState.State [KeyName]到GlobalState [KeyName]的访问.会很好的. (12认同)
  • 中间语言 - .NET的汇编语言. (6认同)
  • FWIW,在 IL 中将属性和默认属性上的 getter 方法的“实例”更改为“静态”会导致 ilasm 抱怨“标记“静态”处存在语法错误”;我不擅长干涉伊利诺伊州的事务,但这听起来至少是一个拒绝。 (2认同)

Jul*_*iet 68

索引器表示法需要引用this.由于静态方法没有对类的特定实例的引用this,因此您不能使用它们,因此您不能在静态方法上使用索引符号.

问题的解决方案是使用单例模式,如下所示:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

现在您可以Utilities.ConfigurationManager["someKey"]使用索引器表示法进行调用.

  • 但为什么索引器必须使用'this'?它不必访问实例数据 (106认同)
  • +1为Malfist的评论.仅仅因为它对实例索引器使用"this"并不意味着它们无法提出其他语法. (80认同)
  • 同意.你是在乞求这个问题.你基本上已经说过不允许的原因是因为它是不允许的.-1因为问题是"为什么不允许?" (40认同)
  • @ xr280xr +1正确使用"乞讨问题":)另外我也有同样的抱怨. (15认同)
  • -1,因为如果实现了静态索引器,此答案假定当前符号是唯一可能的符号.在索引器中使用`this`不一定是必需的,它可能被选择在其他关键词之上,因为它最有意义.对于静态实现,以下语法可能非常可行:`public object static [string value]`.无需在静态上下文中使用关键字`this`. (14认同)
  • 这不是您正在寻找的答案.向前走. (6认同)
  • 我怀疑索引符号"需要引用'this`".索引器表示法可能正在使用*token*`this`,但这与实例方法体中出现的`this`表达式几乎无关. (5认同)
  • -1因为'this'标记用作关键字而不是对'this'对象的引用.扩展方法非常乐意将'this'用作关键字,同时保持静态. (5认同)

Chr*_*isW 7

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

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