代码之家  ›  专栏  ›  技术社区  ›  I. J. Kennedy ShankarSangoli

公共字段与自动属性

  •  310
  • I. J. Kennedy ShankarSangoli  · 技术社区  · 15 年前

    我们经常被告知应该通过为类字段创建getter和setter方法(C#中的属性)来保护封装,而不是将字段公开给外部世界。

    但很多时候,字段只是用来保存一个值,而不需要任何计算来获取或设置。对于这些,我们都会这样做:

    public class Book
    {
        private string _title;
    
        public string Title
        {
              get => _title; 
              set => _title = value;
        }
    }
    

    然后出现了C#3.0,我看到它们添加了自动属性:

    public class Book
    {
        public string Title { get; set; } 
    }
    

    哪一个更整洁,我对此表示感谢,但真的,有什么不同于仅仅建立一个公共领域?

    public class Book
    {
        public string Title;
    }
    
    10 回复  |  直到 4 年前
        1
  •  184
  •   Community VonC    7 年前

    在一个 related question

    Properties vs. Public Variables

    • 反射在变量和属性上的工作方式不同,因此如果依赖于反射,则更容易使用所有属性。
    • 不能针对变量进行数据绑定。
    • 将变量更改为属性是一种突破性的更改。例如:

      TryGetTitle(out book.Title); // requires a variable
      
        2
  •  88
  •   JaredPar    15 年前

    忽略API问题,我发现使用属性最有价值的是调试。

    CLR调试器不支持数据断点(大多数本机调试器都支持)。因此,不可能在类上特定字段的读写上设置断点。这在某些调试场景中非常有限。

    因为属性是作为非常精简的方法实现的,所以可以在读取和写入属性值时设置断点。这让他们在球场上有了很大的优势。

        3
  •  78
  •   Rex M    15 年前

    将字段更改为属性会破坏合同(例如,要求重新编译所有引用代码)。因此,当您与其他类(任何公共(通常受保护)成员)有一个交互点时,您需要为未来的增长进行规划。要做到这一点,请始终使用属性。

        4
  •  67
  •   MartinStettner    14 年前

    只是因为没人提到它:你不能在接口上定义字段。因此,如果您必须实现一个定义属性的特定接口,自动属性有时是一个非常好的特性。

        5
  •  53
  •   Zaid Masud    12 年前

    这是一个经常被忽视的巨大差异,在任何其他答案中都没有提及: . 您可以声明虚拟属性并重写它们,但不能对公共成员字段执行相同的操作。

        6
  •  12
  •   Reed Copsey    15 年前

    这都是关于版本控制和API稳定性的。在版本1中没有区别-但是在以后的版本中,如果您决定在版本2中使用某种类型的错误检查将此属性设置为属性,则不必更改API-除了属性的定义之外,任何地方都不需要更改代码。

        7
  •  11
  •   Arnaldo    11 年前

    与公共字段相比,自动实现属性的另一个优点是,您可以将集合访问器设置为私有或受保护,从而使定义它的对象类比公共字段的对象类具有更好的控制能力。

        8
  •  8
  •   fastcodejava    14 年前

    建立一个领域没有什么错 public getter/setter 具有 private Property ,你还是来吧 .

        9
  •  1
  •   James Black    15 年前

    如果只使用公共属性,那么灵活性就会降低。

    在不违反合同的情况下,额外的灵活性是使用属性对我来说最重要的,而且,在我真正需要灵活性之前,自动生成是最有意义的。

        10
  •  1
  •   Jinlye    4 年前

    有一件事你可以用字段来做,但不能用属性(或者以前不能…我马上就来讨论)就是字段可以指定为 readonly 而属性不能。因此,字段为您提供了一种明确的方式来表明您的意图,即仅在对象实例化时(从构造函数中)设置变量,并且此后不应更改。是的,您可以将属性设置为具有私有setter,但这只是说“这不能从类外部更改”,这与“这不能在实例化后更改”不同-您仍然可以在实例化后从类内部更改它。是的,您可以将属性的backing字段设置为readonly,但这会使实例化后尝试将其更改为运行时错误而不是编译时错误。所以只读字段做了一些有用的事情,而属性却做不到。

    但是,随着C#9的变化,这一点也发生了变化,因此我们得到了以下有用的属性语法:

    public string Height { get; init; }
    

    这表示“这可以从类外使用,但只能在对象初始化时设置”,因此字段的只读优势消失。

        11
  •  0
  •   TrtlBoy    7 年前

    我发现一件非常有用的事情以及所有的代码和测试原因是,如果它是一个属性vs一个字段,那么VisualStudioIDE会显示一个属性而不是字段的引用。

        12
  •  0
  •   KunYu Tsai    4 年前

    我的pov做了一些研究

    1. 验证。
    2. 允许重写访问器以更改属性的行为。
    3. 调试目的。通过在访问器中设置一个断点,我们将能够知道属性何时以及发生了什么变化。
    4. 我们只能有一个字段集。例如,public set()和private get()。这在公共领域是不可能的。