【问题标题】:const Dictionary in c#C#中的常量字典
【发布时间】:2010-10-25 14:56:29
【问题描述】:

我在 C# 中有一个包含字典的类,我想创建它并确保只要包含它的类存在,就不会从该字典中添加、编辑或删除任何内容。

readonly 并没有真正帮助,一旦我测试并看到我可以在之后添加项目。例如,我创建了一个示例:

public class DictContainer
{
    private readonly Dictionary<int, int> myDictionary;

    public DictContainer()
    {
        myDictionary = GetDictionary();
    }

    private Dictionary<int, int> GetDictionary()
    {
        Dictionary<int, int> myDictionary = new Dictionary<int, int>();

        myDictionary.Add(1, 2);
        myDictionary.Add(2, 4);
        myDictionary.Add(3, 6);

        return myDictionary;
    }

    public void Add(int key, int value)
    {
        myDictionary.Add(key, value);
    }

}

我希望 Add 方法不起作用。如果可能的话,我希望它甚至不编译。有什么建议吗?

实际上,我很担心它是开放给很多人更改的代码。因此,即使我隐藏了 Add 方法,也有可能有人“无辜地”创建一个添加密钥或删除另一个密钥的方法。我希望人们查看并知道他们不应该以任何方式更改字典。就像我使用 const 变量一样。

【问题讨论】:

  • 奇怪的要求表明您的设计存在问题。您可能想重新考虑您在这里尝试的内容。否则,您可以轻松创建自己的实现来执行此操作。
  • 您可以实现自己的字典。类似问题:stackoverflow.com/questions/35002/…

标签: c# .net dictionary immutability readonly


【解决方案1】:

完全隐藏字典。只需在 DictContainer 类上提供一个从字典中检索项目的 get 方法。

public class DictContainer
{
    private readonly Dictionary<int, int> myDictionary;

    public DictContainer()
    {
        myDictionary = GetDictionary();
    }

    private Dictionary<int, int> GetDictionary()
    {
        Dictionary<int, int> myDictionary = new Dictionary<int, int>();

        myDictionary.Add(1, 2);
        myDictionary.Add(2, 4);
        myDictionary.Add(3, 6);

        return myDictionary;
    }

    public this[int key]
    {
        return myDictionary[key];
    }
}

【讨论】:

    【解决方案2】:

    不要定义Add 方法。

    保持 myDictionary 变量为私有并公开一个 Getter/Indexer,以便只能从该类外部读取它。..

    【讨论】:

      【解决方案3】:

      没有内置的方法可以做到这一点,考虑使用a wrapper class.

      【讨论】:

        【解决方案4】:
        interface IReadOnlyDic<Key, Value>
        {
            void Add(Key key, Value value);
        }
        class ReadOnlyDic<Key, Value> : Dictionary<Key, Value>, IReadOnlyDic<Key, Value>
        {
            public new void Add(Key key, Value value)
            {
                //throw an exception or do nothing
            }
            #region IReadOnlyDic<Key,Value> Members
        
            void IReadOnlyDic<Key, Value>.Add(Key key, Value value)
            {
                base.Add(key, value);
            }
        
            #endregion
        }
        

        添加自定义项目;

            IReadOnlyDic<int, int> dict = myDictInstance as IReadOnlyDic<int, int>;
            if (dict != null)
                dict.Add(1, 155);
        

        【讨论】:

          【解决方案5】:

          这是另一种方式

          class ReadOnlyDic<Key, Value> : Dictionary<Key, Value>
          {
              private bool _locked = false;
          
              public new void Add(Key key, Value value)
              {
                  if (!_locked)
                  {
                      base.Add(key, value);
                  }
                  else
                  {
                      throw new ReadOnlyException();
                  }
              }
              public void Lock()
              {
                  _locked = true;
              }
          }
          

          【讨论】:

          • +1 以简化解决方案,并与 Dictionary 的界面兼容。然而:为什么使用“new”而不是“override”?此外,除了 Add 之外,Remove 方法也应该被覆盖。
          • @chiccodoro: Dictionary 没有 virtual 方法。
          【解决方案6】:

          仅供参考,现在它已内置于 .net 4.5。

          http://msdn.microsoft.com/en-us/library/gg712875(v=vs.110).aspx

          【讨论】:

            【解决方案7】:

            类似于Neil's answer:

            完全隐藏字典。只需在 DictContainer 类上提供一个从字典中检索项目的 get 方法。如果你想使用 [] 覆盖,你需要 getter settter 方法(至少任何一个 get/set)

            public class DictContainer
            {
                private readonly Dictionary<int, int> myDictionary;
            
                public DictContainer()
                {
                    myDictionary = GetDictionary();
                }
            
                private Dictionary<int, int> GetDictionary()
                {
                    Dictionary<int, int> myDictionary = new Dictionary<int, int>();
            
                    myDictionary.Add(1, 2);
                    myDictionary.Add(2, 4);
                    myDictionary.Add(3, 6);
            
                    return myDictionary;
                }
            
                public this[int key]
                {
                    get => myDictionary[key];
                }
            }
            

            【讨论】:

            • @cigien 我已经更改了函数以使其工作 => public this[int key] { get => myDictionary[key]; }
            • 我不确定你的意思。如果您想修改您的答案以澄清某些问题,请继续。
            猜你喜欢
            • 2016-12-05
            • 2010-09-21
            • 1970-01-01
            • 2014-06-07
            • 1970-01-01
            • 2015-01-06
            • 1970-01-01
            • 1970-01-01
            • 2011-04-20
            相关资源
            最近更新 更多