【问题标题】:What's the reason for peoples to use properties with get; set; instead of fields?人们使用 get 属性的原因是什么?放;而不是字段?
【发布时间】:2020-12-22 14:10:41
【问题描述】:

我经常在类中看到属性,而不是字段。看起来是这样的:

class TestClass
{
    public ulong Id { get; set; }
    public string Description { get; set; }
}

为什么人们会这样做?他们可以改用字段。我在那里至少看到一个专业人士 - 我们可以将带有 ref 关键字的字段传递给函数。是否有任何专业人士出于属性或其他原因像那样使用它们?

【问题讨论】:

    标签: c# properties field


    【解决方案1】:

    主要原因是封装 - 值可以通过相应的属性进行更改,即使您后来决定该属性不应该只返回一个值,情况仍然如此。也许您发现您想在值更改时触发一个事件?如果你有房产,那很容易。如果您有一个公共字段,则需要进行重大更改。

    此外,属性可以是虚拟的或在接口中声明。并且可以将它们声明为只读。

    哦,它有助于调试:如果您想知道谁在更改您的值(意外),您可以在“集合”上设置断点。

    【讨论】:

    • 还有一些严格要求属性的用法,例如WPF 数据绑定。
    • @KlausGütter 这似乎更像是一个先有鸡还是先有蛋的问题......如果字段是编程的主流方式,WPF 数据绑定将支持它们。当您使用反射(如 WPF 数据绑定所做的那样)时,按名称查找属性或按名称查找字段的复杂性相同,并且可以缓存,因此不会减慢代码速度。
    • @xanatos 我不同意 wpf 是先有鸡还是先有蛋的问题。如果您想更新数据绑定,则需要发出一个事件,而这正是本答案中提到的需要属性的场景之一。也许他们也可以在人们确定值永远不会改变或者他们不希望 UI 反映变化的情况下支持字段,但我可以理解为什么他们决定只支持任何一种方式都可以工作的属性,所以要花很多钱更灵活的 wpf 代码。
    • TBH 如果你只是写{ get; set; } 不封装任何东西并且它的工作方式与字段相同。您还可以将{ get; set; } 添加到现有字段并拥有一个属性,而不会有任何向后兼容性问题。
    • @TomasSmagurauskas:不是 100% 正确的。 OP 提到的一种情况是在调用带有 out 参数的方法时使用成员。这是一种罕见的情况,但会在这里中断。此外,命名约定通常不允许这样做。字段使用不同的大小写(通常是前缀),而不是属性。
    【解决方案2】:

    人们使用属性而不是字段主要是由于编码约定。如果它不执行任何 actual 封装(在 POCO 的情况下),那么在 C# 中没有太大区别。大多数时候,可以使用字段而不是属性,而不会产生任何后果。

    // This:
    public string MyValue;
    // Could be later on changed to this:
    public string MyValue { get; set; }
    // With no compatibility issues.
    

    虽然推测为什么约定是它们的方式很有趣。在 C# 中,属性和字段之间的差异从消费者的角度来看大多是隐藏的。在旧语言中不一定是这种情况。 IE。在 Java 中,您必须显式地编写 getter 和 setter 方法。因此,如果您在 Java 中有一个字段,而现在您决定要封装它,那么您需要检查该字段的所有用法并改用 getter 和 setter。如果您使用动态库链接(前段时间曾经是流行的部署方式),这可能是一个更大的问题。正因为如此,从一开始就更容易封装字段,因此您将来不会遇到向后兼容性问题。当然,这些约定也会传播到其他语言。

    【讨论】:

    • 没有兼容性问题 - 不正确。将字段更改为属性是一项重大更改(即使 C# 源代码看起来相同,添加字段与属性的 IL 代码也完全不同)。任何使用这种类型的客户端至少必须重新编译。
    猜你喜欢
    • 1970-01-01
    • 2015-10-28
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    • 2014-08-25
    • 2010-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多