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

C#3.0中自动属性和公共字段的区别,c#,c#-3.0,C#,C# 3.0,我无法理解为什么C#3.0中存在自动实现的属性语言特性 你说的话有什么不同 public string FirstName; 因为它们在生成的IL代码(和机器语言)中的实现方式不同。自动属性仍然作为公共getter和setter公开,而公共字段只是一个字段 因此,实现自动属性允许您在以后的某个日期更改getter或setter的内部行为(如添加验证器),而无需重新编译或重新编码使用它的任何依赖类…第一个是公共字段,而第二个是公共属性 主要区别在于它们的使用方式。例如,WPF只能将数据绑定到属

我无法理解为什么C#3.0中存在自动实现的属性语言特性

你说的话有什么不同

public string FirstName;


因为它们在生成的IL代码(和机器语言)中的实现方式不同。自动属性仍然作为公共getter和setter公开,而公共字段只是一个字段


因此,实现自动属性允许您在以后的某个日期更改getter或setter的内部行为(如添加验证器),而无需重新编译或重新编码使用它的任何依赖类…

第一个是公共字段,而第二个是公共属性


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

不同之处在于,使用读取属性的代码编译的其他程序集是针对属性编译的

如果您以后决定需要向getter或setter添加代码,您可以这样做,而不必强制链接到它的所有其他程序集重新编译

但田野却不是这样。如果您稍后将字段更改为属性,以便添加该代码,那么针对您的链接的其他程序集将停止正常运行,因为它们被编译为读取字段而不是属性


此外,编写大量代码是为了查找属性,而不是字段,例如数据绑定和类似的内容。

考虑一下,如果以后要使用自定义实现将每个属性更改为属性,会发生什么情况。如果是自动实现的属性,只需添加一个字段并更改实现。完全源代码和二进制兼容

如果它是一个字段,那么您既不能获得源代码兼容性,也不能获得二进制兼容性。您必须重建引用它的所有内容,并修复任何不再编译的内容


另外。我个人对字段的主要反对意见是,它在API中公开了一个实现决策。

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

public string FirstName { get; private set; }
类的用户将FirstName视为公共属性。但是,他/她不能给它写信。

因为这种用法:
公共字符串名{get;private set;}


easy属性,即OO规则中的“洁食”自动属性是编译器生成的常规属性,它们与任何常规属性一样使用支持字段,但您无需为此编写代码。以下是编译器生成的代码的示例(感谢):

[CompilerGenerated]
private string <ContentType>k__BackingField;

public string ContentType
{
    [CompilerGenerated]
    get
    {
        return this.<ContentType>k__BackingField;
    }
    [CompilerGenerated]
    set
    {
        this.<ContentType>k__BackingField = value;
    }
}
[编译生成]
私有字符串k__BackingField;
公共字符串内容类型
{
[编译生成]
得到
{
返回此.k__BackingField;
}
[编译生成]
设置
{
this.k_uubackingfield=值;
}
}

一旦产品进入RTM,除Microsoft之外没有人使用该代码名。在我看来,这里所有答案可能重复,这表明这是语言设计中的一个缺陷。当然,这里的问题可以在编译器或运行时级别解决。为什么它必须破坏二进制和源代码的兼容性?为什么我们被迫添加可以优化的样板文件?另外,您可以使用属性进行数据绑定。
[CompilerGenerated]
private string <ContentType>k__BackingField;

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