5

可能的重复项:
c#:为什么使用空的 get 设置属性而不是使用公共成员变量?
C#:公共字段与自动属性

我在我的代码中使用“自动”属性,我想知道这段代码之间的实际区别是什么:

public class foo{
    public int i;
}

public class foo{
    public int i {get; set;}
}

我知道这是有区别的,因为我使用过的 sine 3rd 派对错过了公共成员,但在添加{get; set;}.

由于这背后没有私人领域,幕后发生了什么?

4

3 回答 3

5

使用自动属性时,编译器会生成一个私有字段。

当您如下例所示声明属性时,编译器会创建一个私有的匿名支持字段,该字段只能通过属性的 get 和 set 访问器访问。


关于两个示例之间的区别 - 第一个示例直接公开该字段以进行操作。这被认为是不好的做法(想想信息隐藏、封装丢失)。

对于第二个示例,您必须使用 getter 和 setter,并且可以围绕这些操作添加任何类型的验证和其他逻辑。

请参阅博客文章:

如果我有一个没有特殊行为的字段,我应该编写一个“以防万一”属性(使用微不足道的 get/set),还是应该公开一个公共字段?

库设计指南建议您在此处编写属性的原因是库易于版本控制很重要。如果你提前把一个属性放在那里,你可以改变属性的实现,而不需要用户重新编译他们的代码。

于 2011-01-20T19:52:52.463 回答
1

这是一个自动属性,而不是匿名属性。实际上,它有一个私有的支持字段,它只是由编译器自动生成的,在编译时对您不可用。如果您通过 Reflector 之类的工具运行您的课程(或在运行时使用反射检查它),您将看到支持字段。

要回答“有什么区别?”的问题,显而易见的答案是一个是字段,而一个是属性。使用自动属性的优势在于,它使您可以在以后需要时灵活地移动到传统属性,而无需更改您的 API。至于第三方代码能够“到达”一个但不能“到达”另一个,这将是其他开发人员最好回答的问题。话虽如此,大多数 API 旨在处理属性,而不是字段(因为传统观点是您不会在声明类之外公开字段)。如果第三方库正在反射性地扫描您的类,那么它可能只是在寻找属性。

要记住的重要一点是:

private string backingField;

public string Data
{
    get { return backingField; }
    set { backingField = value; }
}

public string Data { get; set; }

都编译成基本相同的代码。唯一的实质性区别是支持字段的名称。

于 2011-01-20T19:53:48.907 回答
1

第一个是字段,可以描述为 POD。第二个是一个属性,允许派生类重载和影子,而第一个不允许。第二个也很好,因为编译器默默地创建了一个后备存储。

于 2011-01-20T19:55:26.577 回答