私有类变量的字段与属性[重复]

Posted

技术标签:

【中文标题】私有类变量的字段与属性[重复]【英文标题】:Fields vs Properties for private class variables [duplicate] 【发布时间】:2010-12-05 10:37:03 【问题描述】:

对于私有类变量,首选哪一个?

如果您有像int limit 这样的属性,您希望它是:

int Limit get; set;

并在类中使用它,如下所示:

this.Limit

是否有理由使用它或不使用它?也许是出于性能原因?

我想知道这是否是一个好习惯。

【问题讨论】:

【参考方案1】:

拥有私有或受保护的属性并没有错;当存在与基础变量相关的规则或副作用时,这非常有用。

属性对于公共变量来说似乎更自然的原因是,在公共情况下,这是一种对冲未来实现变化的方式,即属性将保持不变,但实现细节会以某种方式移动(和/或将需要一些额外的业务规则)。

在性能方面,这通常是微不足道的,或者对于直接赋值属性实际上是相同的。

我个人不喜欢(但经常使用)简单的赋值属性,因为它们只会使代码混乱。我希望 C# 允许“事后重构”。

【讨论】:

【参考方案2】:

对于私有成员,我只在获取和/或设置值会导致其他事情发生时将其设为属性,例如:

private int Limit

   get
   
       EnsureValue();
       return this._limit;
   

否则,字段很好。如果您需要增加它们的可访问性,这已经是一个足够大的变化,在那时将其作为一个属性并不是什么大不了的事。

编辑:正如 Scott 在 cmets 中提醒我们的那样,属性的副作用通常比其他任何事情都更痛苦。不要违反单一职责并将属性逻辑限制为一致的逻辑操作仅在值上必须在门口完成 - 例如延迟加载(如示例以上),将内部结构转换为公开有用的格式等。

【讨论】:

+1 - 简洁并包含代码示例。 +1 我读了你的代码并且是 WTF。阅读您的帖子后,代码背后的推理变得非常清楚。干得好。 您实际上应该尽量避免使用具有副作用的属性。属性由各种不同的事物评估,包括调试监视、本地、自动窗口和快速监视窗口。因此,具有副作用的属性可能会在调试会话期间导致许多奇怪的行为,并且有时可能使查找运行时错误变得非常困难。 @Scott,确定什么是“副作用”可能会进入很多灰色区域。例如,引发 PropertyChangedNotification 事件怎么样?验证设置到属性中的值怎么样?从数据库中延迟加载值怎么样?对设置到属性中的值进行更改跟踪怎么样?这里有很多事情可以做,不仅仅是简单地设置一个值,而是避免经典的“副作用”问题。【参考方案3】:

属性提供了一些非常好的自动特性(如 Json 和 Xml 序列化)

字段没有。

属性也可以是接口的一部分。如果您决定稍后重构......这可能也是需要考虑的事情。

【讨论】:

【参考方案4】:

我一般遵循以下原则:如果是严格私人使用,则使用字段,因为它更快。

如果您决定某天应该将其公开、受保护或内部化,无论如何重构一个属性并不难,并且使用 ReSharper 等工具大约需要 3 秒... :)

【讨论】:

【参考方案5】:

在我看来,使用属性代替变量归结为:

优点

可以为调试设置断点,正如 Jared 所说, 可能会引起副作用,例如 Rex 的 EnsureValue()getset 可以有不同的访问限制(public get、protected set),李> 可在属性编辑器中使用,

缺点

访问速度较慢,使用方法调用。 大量代码,更难阅读 (IMO)。 更难初始化,比如需要EnsureValue();

并非所有这些都适用于int Limit get; set; 样式属性。

【讨论】:

【参考方案6】:

如果您的数据成员只需要设置和获取逻辑,那么属性是 C# 中非常好的快速解决方案

【讨论】:

【参考方案7】:

自动属性的要点是它们可以非常快速地创建对类中某些字段的公共访问。现在,除了一个大的场外,与将场直接暴露给外界相比,它们没有任何好处。

你的类的接口是它与外界通信的方式。在字段上使用自动属性允许您在以后更改类的内部结构,以防您需要设置该属性的值来执行某些操作或检查授权规则或类似的读取操作。

您已经拥有一个属性这一事实意味着您可以在不破坏公共接口的情况下更改您的实现。

因此,如果这只是一个私有字段,那么自动属性并没有那么有用,不仅如此,而且您不能像使用字段那样在声明时初始化公共属性。

【讨论】:

【参考方案8】:

属性只是语法糖,C# 会将它们编译成get_PropertyNameset_PropertyName,因此性能差异不是考虑因素。

【讨论】:

属性的 getset 等同于方法调用,因此属性较慢。那么为什么说性能差异不是考虑因素呢? 因为它们不是。除了非常特殊的情况外,百万分之一秒的差异一点也不重要。这就像说出于性能原因应该使用 for 而不是 foreach (这比方法与属性访问的区别要大得多)【参考方案9】:

当可访问性为私有时,自动属性对字段的唯一真正好处是您可以在访问和更新变量时设置断点。如果这对您的方案很重要,那么一定要使用自动属性。否则,鉴于没有实质性优势,我选择使用最简单的构造,即字段。

【讨论】:

您在这里缺少的一件事是能够在不更改公共界面的情况下进行未来修改。属性在公共接口稳定性方面为您提供了更多的灵活性。【参考方案10】:

我会说使用属性是一种很好的做法。如果您必须公开限制值并使用本地成员,则需要更多编码,而如果它是属性,则只需要更改其修饰符。

我认为它也更干净。

【讨论】:

【参考方案11】:

当然,因为它是一个私有 API,所以它是一个实现细节 - 你可以在这里做任何你想做的事情。然而,没有理由不使用属性,即使是私有类。属性会被 JIT 内联,除非有额外的代码,所以不会对性能产生真正的影响。

更喜欢 IMO 属性的最大原因是:

    API 的一致性 - 您需要公开公开的 API 中的属性,因此将它们放在私有 API 中将使您的编程体验更加一致,由于更好的可维护性而导致更少的错误 更容易将私有类转换为公共类

【讨论】:

以上是关于私有类变量的字段与属性[重复]的主要内容,如果未能解决你的问题,请参考以下文章

类变量与实例变量析构函数私有属性与私有方法

面向对象的成员: 实例变量 类变量 实例方法 类方法 静态方法 属性 私有

day8-Python学习笔记(十八)面向对象,self,私有,属性方法

无法查看从父类继承的属性 [重复]

属性与公共成员变量[重复]

如何访问派生类中的私有集属性[重复]