【问题标题】:C# Dictionary with Private Add Method or Adjustment Ability具有私有添加方法或调整能力的 C# 字典
【发布时间】:2024-04-27 10:00:02
【问题描述】:

我正在尝试在具有私有 Add 方法/调整值的能力的类中创建一个字典。基本上我希望能够从类外部访问它并查看其中的值,但我不希望任何人能够在不通过类中的方法工作的情况下更改与键关联的值。

我首先尝试创建一个 Dictionary 属性(因此我可以轻松地尝试使用 getter 和 private setter 来做我想做的事情),但后来发现这并不完全可能。

我知道可能有一种方法可以使用自定义方法或自定义单独的类来执行此操作,但我想先在这里查看 C# 中是否有任何方法可以执行此操作。

让我知道你的想法。谢谢!

【问题讨论】:

    标签: c# dictionary properties private


    【解决方案1】:

    您可以使用IReadOnlyDictionary<TKey,TValue> - 它是interface all Dictionary classes implement

    但如果那是您公开的属性的类型,则 没有 没有要调用的 Add() 函数。它有 List 和 Collection “兄弟”,同样的处理。

    请注意,从技术上讲,仍然有人可以将其转换回 Dictionary<TKey,TValue>,从而授予他们完全的 R/W 访问权限。除了安全应用程序之外,这并不真正适用于所有应用程序。如果它很重要,只需分发您内部词典的克隆。

    代码可能如下所示:

    Dictionary<int, string> SecuredCollection = new Dictionary<int, string>();
    
    public IReadOnlyDictionary<int, string> ThatDictionaryUsersCanOnlyRead
    {
        get 
        {
            return SecuredCollection;
        }
    }
    

    【讨论】:

    • 感谢您的回答。但是,如果您使用上面的代码,您真的需要使用 IReadOnlyDictionary 吗?那你就不能用字典吗?
    • 正如他在答案中解释的那样,IReadOnlyDictionary 没有要调用的 Add 函数(根据您对调用者无法添加值的要求)。如果您只是将 Dictionary 传回,它将具有您希望避免的 Add() 实现。通过在您的类中创建它,并将其仅作为IReadOnlyDictionary 公开,调用者将只能使用IReadOnlyDictionary 提供的方法。
    • 啊,我明白了。那是相当安全的。说得通。实际上充当具有私有设置器的属性。我可以使用 SecruredCollection 在课堂内更改它,但不能从课堂外使用它。谢谢,大有帮助。另外,为了清楚起见,他忘记为 IReadOnlyDictionary 添加变量名,对吗?我想,我并没有错过什么,但是嘿,你永远不知道。
    • @whathm 我确实忘记了属性名称。当您纯粹在网站上写作时,就会发生这种情况。我现在修好了。
    • @Christopher 正是我的想法,我不怪你。现在很有意义,谢谢您的回答。
    【解决方案2】:

    如果我错了,请纠正我,但我相信另一种解决方案是简单地返回一个新的Dictionary,但将所需的Dictionary 作为新的Dictionary's 构造函数的参数。类似于@Christopher 的回答,但没有IReadOnlyDictionary

    这样,即使有人试图调整它,它也会失败。但是,我想这意味着它应该附带免责声明,对于不知道它提供克隆的人来说,这将是非常误导的。话虽如此,我得出的结论是这是一种替代方案,但@Christopher 的解决方案是更好的解决方案。

    private Dictionary<int, string> legitDictionary = new Dictionary<int, string>();
    
    public Dictionary<int, string> ClonedDictionary
    {
        get 
        {
            return new Dictionary<int, string>(legitDictionary);
        }
    }
    

    【讨论】:

      【解决方案3】:

      不可能以仅涉及属性的方式进行。完成您想要的事情的自然方法是使用方法:

      public class MyClass
      {
          private readonly Dictionary<string, string> users = new Dictionary<string, string>();
      
          public void Set(string key, string value)
          {
              if (users.ContainsKey(key))
              {
                  users[key] = value;
              }
              else
              {
                  users.Add(key, value);
              }
          }
      
          public IDictionary<string, string> ListUsers() 
          {
              return users;
          }
      }
      

      注意:设置方法是公开的。您可以使用任何访问说明符,例如私有。

      【讨论】:

      • 另一个答案显示了如何使用属性执行请求...并且此答案中的代码显示了如何防止使用.ListUser().Add("foo", "bar")
      最近更新 更多