public int i和public int i之间有什么区别{get; set;}(自动属性和公共成员之间有什么区别?)

时间:2011-01-20 19:50:14

标签: c#

  

可能重复:
  c#: why have empty get set properties instead of using a public member variable?
  C#: Public Fields versus Automatic Properties

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

public class foo{
    public int i;
}

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

我知道存在差异,因为我使用的正常第三方错过了公众成员但是在添加{get; set;}后发现了他们。

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

3 个答案:

答案 0 :(得分:5)

使用automatic properties时,编译器会生成一个私有字段。

  

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


关于两个例子之间的区别 - 第一个例子直接暴露了字段以进行操作。这被认为是不好的做法(认为信息隐藏,丢失封装)。

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

请参阅this博文:

  

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

     

图书馆设计指南建议您在此处编写属性的原因是,对库进行简单版本化非常重要。如果您提前在其中放置属性,则可以更改属性实现,而无需用户重新编译其代码。

答案 1 :(得分:1)

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

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

要记住的重要事项是:

private string backingField;

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

public string Data { get; set; }

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

答案 2 :(得分:1)

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