【问题标题】:When should you use a field rather than a property?什么时候应该使用字段而不是属性?
【发布时间】:2010-10-13 02:24:25
【问题描述】:

任何人都可以清楚地表达您在类设计中何时使用字段以及何时使用属性?

考虑:

public string Name;

或者:

private string _Name;
public string Name
{
   get { return _Name; }
   set { _Name = value; }
}

我意识到第二种方法更合适,更灵活,所以我通常尝试使用这种方法。

但是为什么我看到人们使用第一种方法呢?他们只是懒惰,还是在某些特定情况下这是正确的选择?这只是偏好问题吗?

【问题讨论】:

  • 顺便说一句,为您的私人成员使用下划线并不是 .NET 做事的方式。查看msdn.microsoft.com/en-us/library/ms229045.aspx
  • 您将字段与属性混为一谈。公共字符串名称;是公共字段而不是属性。
  • +1 乔纳森·帕克的评论。迪恩,您介意我们编辑问题以使用正确的术语吗?
  • 我编辑了它,因为我已经发布了错误的回复;-p

标签: c# theory


【解决方案1】:

上面定义的属性就像 getter 和 setter。使用属性的唯一好处是您可以将其视为具有访问限制的变量。

public string Name { get; private set; }

此属性可以公开访问,但只能私下设置。 (您现在不会希望任何人未经您的同意更改您的名字!;))

【讨论】:

    【解决方案2】:

    在 C# 3.0 中,您实际上可以编写:

    public string Name {get; set;}
    

    这让你既得体又懒惰。

    一般来说,通过属性,您可以获得适当的封装。您可以选择允许设置值或获取值,或两者兼而有之。使用公共成员,您没有该选项。

    这可能是一方面的偏好,一方面是您的团队决定如何处理快速和肮脏的类定义,但我想说的是,使用 get/sets 的属性。

    回答

    任何人都可以清楚地说明您何时使用属性以及何时在类设计中使用属性?

    您永远不应该使用公共属性。您应该始终使用属性。它更安全、更灵活。也就是说,人们会很懒惰,只会使用公共成员。但是,在 C# 3.0 中,您可以使用更简洁的语法来定义属性,这应该可以满足您内心的懒惰。

    只需键入prop 并点击<tab> 即可加快添加属性的懒惰。

    【讨论】:

    • 请注意:在谈论代码时,您永远不应该说“不应该”。
    • “你永远不应该使用公共属性”听起来更像是个人意见而不是技术答案
    【解决方案3】:

    除了已经给出的首选属性的原因之外,System.ComponentModel 中还有很多很酷的东西与数据绑定和仅适用于属性而不是字段的更改通知有关。例如,查看有关 PropertyChangedHandler 的文档。

    【讨论】:

      【解决方案4】:

      当您公开该字段时,您允许用户对该字段执行任何他们想做的事情。他们可以分配意外值、无效值、可能导致溢出的值等。

      通过该属性,您可以控制是否允许为字段设置新值、在存储之前对值进行按摩、通知相关方有关字段值的更改等。以及返回值的相同想法通过吸气剂。对于 2.0 以上的 .NET 框架,您可以为 getter、setter 设置访问器。比如说,您只希望用户对该字段只有读取权限,然后您将 getter 设为公开,但将 setter 设为私有或受保护。

      【讨论】:

        【解决方案5】:

        使用属性可以控制它的安全性:

        public string Foo { protected get; private set; }
        

        属性提供了引发事件的简单方法:

        public string Foo
        {
          get { return _foo; }
        }
        set
        {
          bool cancel = false;
          if(BeforeEvent != null) // EventHandler<CancelEventArgs> BeforeEvent
          {
            CancelEventArgs e = new CancelEventArgs();
            BeforeEvent(this, e);
            cancel = e.Cancel;
          }
          if(!cancel)
          {
            _foo = value;
            if(AfterEvent != null) // EventHandler<EventArgs> AfterEvent
            {
              AfterEvent(this, new EventArgs());
            }
          }
        }
        

        我也经常使用这样的代码:

        string Foo
        {
          set
          {
            IsFooSet = value != null;
          }
        }
        
        bool IsFooSet
        {
          get { return _isFoo; }
          set
          { 
           _isFoo = value;
           if(value) // some event raise or controls on form change
          }
        }
        

        【讨论】:

          【解决方案6】:

          Alan 回复的一些附加信息:

          public string Name {get; set;}
          

          一样
          private string _Name;
          
          public string Name{   
          get { return _Name; }   
          set { _Name = value; }
          }
          

          如果你想禁止名称的设置功能,你可以有

          公共字符串名称 {get; 私人设置;}

          【讨论】:

            【解决方案7】:

            属性比字段更易于维护,您可以在 setter/getter 中封装逻辑,从而隐藏实现。

            它们还使重构更容易。

            更多信息:

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2019-06-15
              • 2011-06-22
              • 2015-12-11
              • 2012-02-12
              • 2012-06-27
              • 2010-11-29
              • 2015-12-23
              相关资源
              最近更新 更多