我们经常被告知,应该通过为类字段创建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调试器不支持数据断点(大多数本机调试器支持)。因此,不可能在类的特定字段的读或写上设置断点。这在某些调试场景中非常有限。

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

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

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

在我前段时间遇到的一个相关问题中,有一个链接指向Jeff博客上的一篇文章,解释了一些不同之处。

属性与公共变量

反射在变量和属性上的工作方式不同,因此如果依赖于反射,则更容易使用所有属性。 你不能对变量进行数据绑定。 将变量更改为属性是破坏性的更改。例如: TryGetTitle (book.Title);//需要一个变量

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