我们经常被告知,应该通过为类字段创建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;
}

当前回答

公开一个字段并没有什么错。但是请记住,使用私有字段创建getter/setter不是封装。在我看来,如果你不关心物业的其他功能,你不妨将其公开。

其他回答

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

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

因为属性是作为非常薄的方法实现的,所以可以在其值的读写上设置断点。这让它们在田野上占据了很大的优势。

我的丈夫做了一些调查

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

它确实给了我们更多的可能性和可扩展性。

One thing you can do with Fields but not with Properties (or didn't used to be able to ... I'll come to that in a moment) is that Fields can be designated as readonly whereas Properties cannot. So Fields give you a clear way of indicating your intention that a variable is there to be set (from within the constructor) at object-instantiation time only and should not be changed thereafter. Yes, you can set a Property to have a private setter, but that just says "this is not to be changed from outside the class", which is not the same as "this is not to be changed after instantiation" - you can still change it post-instantiation from within the class. And yes you can set the backing field of your property to be readonly, but that moves post-instantiation attempts to change it to being run-time errors rather than compile-time errors. So readonly Fields did something useful which Properties cannot.

然而,这在c# 9中发生了变化,我们得到了下面这些有用的属性语法:

public string Height { get; init; }

它说“这个可以从类外使用,但它只能在对象初始化时设置”,因此Fields的只读优势消失了。

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

公开一个字段并没有什么错。但是请记住,使用私有字段创建getter/setter不是封装。在我看来,如果你不关心物业的其他功能,你不妨将其公开。