C# 公共字段与自动属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1180860/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 10:12:17  来源:igfitidea点击:

Public Fields versus Automatic Properties

c#classpropertiesfieldautomatic-properties

提问by I. J. Kennedy

We're often told we should protect encapsulation by making getter and setter methods (properties in C#) for class fields, instead of exposing the fields to the outside world.

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

But there are many times when a field is just there to hold a value and doesn't require any computation to get or set. For these we would all do this number:

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

public class Book
{
    private string _title;

    public string Title
    {
          get{ return _title;  }
          set{ _title = value; }
    }
}

Well, I have a confession, I couldn't bear writing all that (really, it wasn't having to write it, it was having to look at it), so I went rogue and used public fields.

好吧,我承认,我无法忍受写所有这些(实际上,不是必须写它,而是必须查看它),所以我流氓并使用了公共领域。

Then along comes C# 3.0 and I see they added automatic properties:

然后是 C# 3.0,我看到他们添加了自动属性:

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

which is tidier, and I'm thankful for it, but really, what's so different than just making a public field?

哪个更整洁,我很感激它,但实际上,与仅仅制作一个公共领域有什么不同?

public class Book
{
    public string Title;
}

采纳答案by Michael Stum

In a related questionI had some time ago, there was a link to a posting on Jeff's blog, explaining some differences.

在我前段时间遇到的一个相关问题中,有一个链接到 Jeff 的博客上的帖子,解释了一些差异。

Properties vs. Public Variables

属性与公共变量

  • Reflection works differently on variables vs. properties, so if you rely on reflection, it's easier to use all properties.
  • You can't databind against a variable.
  • Changing a variable to a property is a breaking change. For example:

    TryGetTitle(out book.Title); // requires a variable
    
  • 反射在变量和属性上的工作方式不同,所以如果你依赖反射,使用所有属性会更容易。
  • 您不能对变量进行数据绑定。
  • 将变量更改为属性是一项重大更改。例如:

    TryGetTitle(out book.Title); // requires a variable
    

回答by Rex M

Changing from a field to a property breaks the contract (e.g. requires all referencing code to be recompiled). So when you have an interaction point with other classes - any public (and generally protected) member, you want to plan for future growth. Do so by always using properties.

从字段更改为属性违反了约定(例如,需要重新编译所有引用代码)。因此,当您与其他类(任何公共(通常受保护)的成员)有交互点时,您希望为未来的增长做计划。通过始终使用属性来做到这一点。

It's nothing to make it an auto-property today, and 3 months down the line realize you want to make it lazy-loaded, and put a null check in the getter. If you had used a field, this is a recompile change at best and impossible at worst, depending on who & what else relies on your assemblies.

今天让它成为自动属性没什么,3 个月后意识到你想让它延迟加载,并在 getter 中进行空检查。如果您使用了一个字段,这在最好的情况下是重新编译更改,在最坏的情况下是不可能的,这取决于谁以及其他什么依赖于您的程序集。

回答by Reed Copsey

It's all about versioning and API stability. There is no difference, in version 1 - but later, if you decide you need to make this a property with some type of error checking in version 2, you don't have to change your API- no code changes, anywhere, other than the definition of the property.

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

回答by JaredPar

Ignoring the API issues, the thing I find most valuable about using a property is debugging.

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

The CLR debugger does not support data break points (most native debuggers do). Hence it's not possible to set a break point on the read or write of a particular field on a class. This is very limiting in certain debugging scenarios.

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

Because properties are implemented as very thin methods, it is possible to set breakpoints on the read and write of their values. This gives them a big leg up over fields.

因为属性被实现为非常瘦的方法,所以可以在读取和写入它们的值时设置断点。这让他们在田野上占了上风。

回答by James Black

If you decide later to check that the title is unique, by comparing to a collection or a database, you can do that in the property without changing any code that depends on it.

如果您稍后决定检查标题是否唯一,通过与集合或数据库进行比较,您可以在属性中执行此操作,而无需更改任何依赖于它的代码。

If you go with just a public attribute then you will have less flexibility.

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

The extra flexibility without breaking the contract is what is most important to me about using properties, and, until I actually need the flexibility, auto-generation makes the most sense.

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

回答by MartinStettner

Just because no one mentioned it: You can't define fields on Interfaces. So, if you have to implement a specific interface which defines properties, auto-properties sometimes are a really nice feature.

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

回答by fastcodejava

There is nothing wrong in making a field public. But remember creating getter/setterwith privatefields is no encapsulation. IMO, If you do not care about other features of a Property, you might as well make it public.

制作一个字段没有错public。但请记住,getter/setter使用private字段创建不是封装。IMO,如果您不关心 a 的其他功能Property,您不妨制作它public

回答by Zaid Masud

A huge difference that is often overlooked and is not mentioned in any other answer: overriding. You can declare properties virtual and override them whereas you cannot do the same for public member fields.

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

回答by Arnaldo

Another advantage of auto-implemented properties over public fields is that you can make set accessors private or protected, providing the class of objects where it was defined better control than that of public fields.

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

回答by TrtlBoy

One thing I find very useful as well as all the code and testing reasons is that if it is a property vs a field is that the Visual Studio IDE shows you the references for a property but not a field.

我发现非常有用的一件事以及所有代码和测试原因是,如果它是属性还是字段,则 Visual Studio IDE 会向您显示属性的引用,而不是字段。