C# 3.0中自动属性和公共字段的区别

19

我不理解为什么C# 3.0引入了auto implemented property语言特性。

当你这样说时,它有什么区别呢?

public string FirstName;
public string FirstName { get; set; }

一旦产品发布,Microsoft以外的人不再使用代号。 - John Saunders
可能是在C# 3.0+中属性和字段的区别的重复问题。 - nawfal
这里所有的答案似乎都指向这是语言设计上的缺陷。显然,这里的问题可以在编译器或运行时层面解决。为什么它必须破坏二进制和源代码的兼容性?我们为什么被迫添加可以优化掉的样板代码? - Andy Baker
7个回答

21
因为它们在生成的IL代码(和机器语言)中的实现方式不同。自动属性仍然作为公共的getter和setter公开,而公共字段只是一个单独的字段。
因此,实现自动属性允许您在稍后更改getter或setter的内部行为(例如添加验证器),而无需重新编译或重新编码任何使用它的依赖类...

9
此外,您可以使用属性进行数据绑定。 - Joel Coehoorn

10

只是为了补充其他人所说的,声明公共字段,该字段可读可写。声明公共自动属性,虽然属性是公共的,但仍然可以添加修饰符来控制对 get/set 级别的可访问性。

public string FirstName { get; private set; }

您的类的用户将FirstName视为公共属性。但是,他/她无法对其进行写操作。


6
考虑一下,如果您以后想将它们都更改为具有自定义实现的属性,会发生什么情况。如果它是自动实现的属性,您只需添加一个字段并更改实现即可。完全支持源代码和二进制兼容性。
如果它一开始就是一个字段,那么您既没有源代码兼容性,也没有二进制兼容性。您必须重新构建所有引用它的内容,并修复任何不再编译的内容。
此外,属性比字段具有各种好处。我个人对字段的主要反感之处在于它在API中暴露了一个实现决策。

2
区别在于,其他使用读取属性的代码编译的程序集是针对属性进行编译的。
如果您稍后决定需要向getter或setter添加代码,则可以这样做,而无需强制每个链接到它的其他程序集重新编译。
但是字段不行。如果您稍后更改字段以成为属性,以添加该代码,那么链接到您的其他程序集将无法正常工作,因为它们编译为读取字段而不是属性。
此外,许多代码都是编写用于查找属性而不是字段,例如数据绑定等。

2

因此使用:
public string FirstName { get; private set; }
这是一个易于使用的属性,符合面向对象编程规则。


0

自动属性是编译器生成的常规属性,它们使用像任何常规属性一样的后备字段,但您不需要编写该代码。这里是一个非常有说明性的示例(感谢Reflector)编译器生成的代码:

[CompilerGenerated]
private string <ContentType>k__BackingField;

public string ContentType
{
    [CompilerGenerated]
    get
    {
        return this.<ContentType>k__BackingField;
    }
    [CompilerGenerated]
    set
    {
        this.<ContentType>k__BackingField = value;
    }
}

0
第一个是公共字段,而第二个是公共属性。
它们的主要区别在于使用方式。例如,WPF只能将数据绑定到属性,而不能绑定到字段。

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