C# 在类内部时,调用其私有成员还是调用其公共属性更好?

C# 在类内部时,调用其私有成员还是调用其公共属性更好?,c#,variables,properties,C#,Variables,Properties,这是我在代码中经常遇到的问题。假设我们有以下代码: public class MyClass { private string _myVariable; public string MyVariable { get { return _myVariable; } set { _myVariable = value; } } public void MyMethod() { string usingPrivateM

这是我在代码中经常遇到的问题。假设我们有以下代码:

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将业务逻辑添加到方法B中,那么即使当前没有业务逻辑,您也可以通过始终调用它来确保安全


一般的共识是什么?

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

场景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;
    }
}
//假设一个假设的类位置
公共阶级圈子
{
私有整数半径;
私人int_XPO;
私人国际组织;
公共整数半径{get{return_Radius;}}
公共职位中心{获取{返回新职位(_xpos,_ypos);}
公共布尔点圆圈(其他位置)
{
返回距离(此中心,其他)<此半径;
}
}
显然,PointInCircle的行为应该与用户在其中执行代码的行为相同。因此,使用公共财产是有意义的


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

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

private int timeSinceLastPropertyAccess;

public int TimeSinceLastPropertyAccess
{
   get 
   { 
      // Reset timeSinceLastPropertyAccess to 0
      int a = timeSinceLastPropertyAccess; 
      timeSinceLastPropertyAccess = 0; 
      return a; 
   }
}
是否希望TimesInclastPropertyAccess在类内使用时重置?

使用该属性

我认为该地产应全权负责管理该油田

有很多实现并不重要,但也有很多实现确实重要——很多。此外,这可能是一个有点痛苦的跟踪,因为它总是看起来正确


调用属性的错误次数比调用字段的错误次数要少得多,如果有此规则的例外情况,请记录其基本原理。

再补充一点,您的示例只询问了getter。另一半是二传手

有时您希望对象使用setter,有时您希望它绕过setter,只分配底层字段

例如,假设您有一个名为IsModified的属性。当对象被修改时,它会告诉您。如果为一个基础字段指定了不同的值,则可以让所有设置程序将其翻转为true


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

视情况而定,您想执行属性的功能吗?private/public并不重要,它就像调用函数一样

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

这样做的问题是,你可能会发现你想在某些地方访问它时做一件事,在其他地方访问它时做另一件事,因此你仍然需要在其中一个地方更改对它的所有“调用”

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


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

这是一个非常糟糕的吸气剂设计。get方法不应该修改状态。这是真的,但是它显示了如果使用的吸气剂可以有不希望的效果。考虑我们在同一个类内拥有这些属性。因此,吸气剂是否足够大,有大的副作用完全是你自己的选择。例如,它应该在哪里重置。感谢您找到这些!我尝试过搜索,但我猜我没有使用正确的关键字进行搜索。因此搜索仍然很差,您是否尝试过Google和“site:stackoverflow.com”?使用该属性的一个优点是,您可以在每次读/写时设置断点。这在大型UNF上特别有用miliar代码库。它允许您在调试器中跳过大块代码,但在修改属性时仍会停止。非常方便。在使用存根进行单元测试时也很方便,因为您可以在存根属性上设置值,但不能在私有成员上设置值。