【问题标题】:When inside a class, is it better to call its private members or its public properties? [duplicate]在一个类中,调用它的私有成员还是它的公共属性更好? [复制]
【发布时间】:2011-01-10 06:07:59
【问题描述】:

这是我在代码中一直纠结的问题。假设我们有以下代码:

public class MyClass {
    private string _myVariable;

    public string MyVariable {
        get { return _myVariable; }
        set { _myVariable = value; }
    }

    public void MyMethod() {
        string usingPrivateMember = _myVariable; // method A
        string usingPublicProperty = MyVariable; // method B
    }
}

哪种方法更正确 - 方法 A 或 B?我总是为此感到难过。方法 A 似乎会更快,因为它不必在获取实际变量之前访问属性。但是,方法 B 更安全,因为如果 MyVariable 的 getter 将业务逻辑添加到其中,则始终调用它是安全的,即使当前没有业务逻辑也是如此。

普遍的共识是什么?

【问题讨论】:

  • 感谢您找到这些!我尝试搜索,但我想我没有使用正确的关键字进行搜索。
  • SO 搜索仍然很差,你试过谷歌和'site:stackoverflow.com'吗?

标签: c# variables properties


【解决方案1】:

使用属性。

我认为物业应该全权负责管理该领域。

有很多实现并不重要,但也有很多重要的地方——很多。另外,这可能有点麻烦,因为它总是看起来正确。

调用属性的次数比调用字段的次数少得多,并且在此规则例外的地方,请记录理由。

【讨论】:

  • 使用该属性的一个优点是您可以在每次读/写时设置一个断点。这在大型、不熟悉的代码库上特别有用。它允许您在调试器中跳过大块代码,但在修改属性时仍会停止。非常方便。
  • 在使用存根进行单元测试时也很方便,因为您可以在存根属性上设置值,但不能在私有成员上设置值。
【解决方案2】:

这实际上取决于您访问该属性的目的。考虑以下两种情况:

场景 1:您编写一个方法来对类中的数据提供通用操作:

// assume a hypothetical class Position

public class Circle
{
    private int _radius;
    private int _xpos;
    private int _ypos;

    public int Radius { get { return _radius; } }
    public Position Center { get { return new Position(_xpos, _ypos); } }

    public bool PointInCircle(Position other)
    {
         return distance(this.Center, other) < this.Radius;
    }
}

显然,PointInCircle 的行为应该与用户执行其中的代码相同。因此,使用公共属性是有意义的。

场景 2:您编写一个方法来操作底层数据。一个很好的例子是序列化。您可能希望序列化底层数据成员,而不是属性访问器返回的值。

【讨论】:

    【解决方案3】:

    取决于,如果您访问该属性,可能会调用“验证”代码。

    private int timeSinceLastPropertyAccess;
    
    public int TimeSinceLastPropertyAccess
    {
       get 
       { 
          // Reset timeSinceLastPropertyAccess to 0
          int a = timeSinceLastPropertyAccess; 
          timeSinceLastPropertyAccess = 0; 
          return a; 
       }
    }
    

    您是否希望在课堂内使用 timeSinceLastPropertyAccess 时重置它?

    【讨论】:

    • 这是非常糟糕的吸气剂设计。 Get 方法不应修改状态。
    • 太正确了,但它表明如果使用 getter 可能会产生不良影响。
    • 考虑到我们正在谈论的是在具有这些属性的同一个类中。因此,getter 是否糟糕到产生严重的副作用完全是您自己的选择。
    • 我们去,一个更好的例子,它应该在哪里重置。
    【解决方案4】:

    再补充一件事,你的例子只询问了吸气剂。另一半是二传手。

    有时您希望对象使用设置器,有时您希望它绕过它们并仅分配基础字段。

    例如,假设您有一个名为 IsModified 的属性。每当对象被修改时,它会告诉你。如果为其中一个基础字段分配了不同的值,您可以让所有的设置器将此设置为 true。

    现在,如果您正在对该对象进行水合(从数据库或其他地方加载),那么您不希望设置 IsModified。因为,坦率地说,它还没有被修改。因此,在该方法中,您使用基础字段名称,但在所有其他方法中,您使用属性设置器。

    【讨论】:

      【解决方案5】:

      这取决于,你想做什么财产?私有/公共并不重要,就像调用一个函数一样。

      实际上,您实际上只是设置了一个“函数”,以期在访问或更改该值时必须执行某些操作。

      这样做的问题是你可能会发现你想做一件事,它在某些地方被访问,而另一个当它在其他地方被访问,所以你仍然必须改变所有的“调用”在其中一个地方给它。

      事实上,如果所有访问该变量的东西——甚至是私有类函数——都是通过刚刚通过变量的属性来实现的,那么为什么还要费心去拥有这个属性呢?为什么不直接创建名为“MyVariable”的变量,然后如果您发现在更改/访问它时想做某事,只需创建另一个名为 _MyVariable 的变量或其他变量,然后将 MyVariable 更改为 _MyVariable 的属性。

      您应该将属性视为就像您过去编写的 accessor() 和 mutator() 函数一样,使用它们的技巧是,如果您发现您确实想要在变量被“访问”时执行一些代码您必须更改对该变量的所有调用以使用访问器(调用函数,而不仅仅是访问成员变量),这就是为什么您将创建“默认”访问器和斗牛士,以防万一。正如我上面所说,c# 和属性没有这个问题(除了在一个蹩脚的情况下,如果它是一个属性,你就不能写入成员的子成员......为什么??)

      【讨论】:

        猜你喜欢
        • 2011-01-18
        • 2017-04-02
        • 1970-01-01
        • 1970-01-01
        • 2015-05-04
        • 2016-03-27
        • 2013-02-13
        • 2013-10-10
        • 1970-01-01
        相关资源
        最近更新 更多