【问题标题】:What is the purpose of this approach to access modifiers?这种访问修饰符的方法的目的是什么?
【发布时间】:2012-05-05 07:25:31
【问题描述】:

考虑以下代码:

    private string _text = null;
    private string[] _values = null;

    public string Text { get { return _text; } }
    public string[] Values { get { return _values; } }

这有什么作用,而只有公共成员无法做到?

【问题讨论】:

  • 请注意,在将数组作为类的只读属性公开时,您应该非常非常小心数组引用是只读的,但数组内容不是。这个类的用户可以随意改变数组的内容。如果这不是可取的,则返回 ReadOnlyCollection<string>,而不是 string[]
  • Eric对此话题的详细思考:blogs.msdn.com/b/ericlippert/archive/2008/09/22/…

标签: c# access-modifiers


【解决方案1】:

通过使用属性而不是公共字段,您可以隐藏实现。

如果在某些时候您需要更改 Text 和 Values 属性返回的内容,您可以在不更改类 API 的情况下更改行为。

此外,此习惯用法将外部对公开数据的访问限制为只读。

【讨论】:

  • 改写了只读访问的问题,希望这不是歧义。感谢@AdamHouldsworth!
【解决方案2】:

这是为了使值只读,虽然我更倾向于这样写:

public string Text { get; private set;}
public string[] Values { get; private set; }

【讨论】:

  • 这只会使值只读到类外的东西。
  • @AdamHouldsworth 我不反对。
  • 只是澄清一下,因为抛出诸如 readonly 之类的词可能会与 readonly 关键字混淆。
  • 进一步,您可以更好地控制访问(验证)并实现一些更高级的东西,例如INotifyPropertyChanged
  • 小心! Values 是“只读的”,因此_values 不能被覆盖,但是写入Values[i] = something 是完全合法的,现在数组的内容会发生变化。因此,除了非常特殊的“只读”定义之外,它不会“使值成为只读”。
【解决方案3】:

此代码将允许外部实体读取您的值,而您的内部代码可以修改支持字段。

您可以使用自动属性来简写:

public string Text { get; private set; }
public string[] Values { get; private set; }

使用公共字段,您将无法同时防止外部修改和支持内部修改。

即使您想将字段公开为外部可写,我仍然建议将事物封装在属性中 - 您永远不知道是否需要在不破坏外部合同的情况下在内部支持某些内容(set/get 中的自定义代码给出你空间来做这件事)。

更不用说大多数数据绑定框架看不到字段,只有属性。

【讨论】:

    【解决方案4】:

    _text_values 只能在定义它们的类中设置,但可以通过属性访问它们的值。

    【讨论】:

      【解决方案5】:

      在您的示例中,它将属性设置为只读,但也有其他用途。

      public string Text { get { return _text; } }
      

      如果您想在 return_text 内部执行一些操作,然后针对 proeperty Text 返回它,您可以这样做。

      public string Text { get { return _text.ToUpper(); } }
      

      这是Encapsulation字段

      封装有时被称为第一支柱或 面向对象程序设计原理。根据原理 在封装方面,一个类或结构可以指定每一个的可访问性 它的成员是在类或结构之外编写代码。方法和 不打算从类外部使用的变量 或组装可以隐藏以限制编码错误的可能性或 恶意攻击。

      考虑以下示例:

      // private field
          private DateTime date;
      
      
          // Public property exposes date field safely.
          public DateTime Date 
          {
              get 
              {
                  return date;
              }
              set 
              {
                  // Set some reasonable boundaries for likely birth dates.
                  if (value.Year > 1900 && value.Year <= DateTime.Today.Year)
                  {
                      date = value;
                  }
                  else
                      throw new ArgumentOutOfRangeException();
              }
      
          }
      

      在此示例中,有一个私有字段 date,它通过属性 Date 公开。现在,如果您想设置日期的边界,那么您可以看到属性的设置部分。

      【讨论】:

        猜你喜欢
        • 2014-09-14
        • 2013-03-17
        • 1970-01-01
        • 2015-07-12
        • 2016-12-11
        • 2014-09-08
        • 2011-02-01
        相关资源
        最近更新 更多