自动属性,带或不带支持字段 - 偏好?

11

我知道使用自动属性时,编译器会在幕后创建自己的后备字段。然而,在我阅读的许多程序中以进行学习时,我看到人们明确地编写

private int _backingField;

public int Property { get { return _backingField; } }

以上和以下有什么区别?

public int Property { get; private set; }

我知道在属性的getter或setter中实际存在副作用时使用属性是很明显的,但这通常并非如此。此外,我知道在结构体的情况下必须显式使用后备字段,无法通过属性访问它们的成员。

我找到的唯一区别是在定义属性的类内部调用值的方式不同。那么,是简单的偏好还是通过属性调用值和直接访问字段有更多差异?是简单的约定吗?

1个回答

14

这两个代码片段之间没有太大的区别 - 例如,你无法通过引用传递属性,但这很少成为问题。然而,如果你想让该字段只读,就像这样:

private readonly int _backingField;    
public int Property { get { return _backingField; } }

然后有所不同。我上面编写的代码防止在类内部更改值,清楚地表明这确实是不可变的。我真的很想能够声明一个只读字段,并使用只读自动实现属性,在构造函数中设置唯一的值 - 但目前还没有这个功能。

顺便说一句,这相当令人困惑:

此外,我理解在结构体的情况下必须明确使用后备字段,不能通过属性访问其成员。

你的意思是什么?你绝对可以在结构体中使用属性。你是在谈论后备字段,它们是可变的结构体,即以下两者之间的区别:

foo.someField.X = 10;

foo.SomeProperty.X = 10;

如果是这样的话,我通常通过一开始将结构体设置为不可变来避免这个问题 :)


1
以XNA的Vector2为例,如果我这样说: public Vector2 TheVector { get; set; }我不能调用 TheVector.X = 10; 相反,我必须使用实际字段。这与按值/引用传递有关。(作为附注,您是否有一些阅读材料可以澄清C#中按值/引用传递的问题?) - Taelia
另外,如果我的两个示例真的没有区别,为什么还有这么多人明确地创建一个后备字段(没有实际目的)? - Taelia
@Taelia:没错,这是可变结构体的情况——我通常会避免使用它。这是因为该属性返回值的副本。至于其他人为什么这样做,我不打算解释原因。 - Jon Skeet
@Taelia 自动属性是在C# 3.0中引入的。这可以解释为什么有些开发人员使用自动属性,而有些则不使用。因为一些使用早期版本的开发人员可能更喜欢“老方法”。 - Terkel
好的,谢谢你们两个。我经常看到这种情况发生,让我怀疑不创建显式字段是否正确。如果没有差别,那我将继续写没有它们的代码。 - Taelia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接