这是我在代码中一直在努力解决的问题。假设我们有以下代码:
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添加了业务逻辑,即使没有当前的业务逻辑,也可以通过调用它来保证安全。
普遍的共识是什么?
答案 0 :(得分:12)
使用该属性。
我认为该财产应该全权负责管理该领域。
有很多实施方案无关紧要,但有很多方面很重要 - 很多。另外,追踪这可能有点痛苦,因为它总是看起来正确。
调用该属性的次数远远少于调用该字段的次数,并且是此规则的例外情况,请记录该基本原理。
答案 1 :(得分:1)
这实际上取决于您访问该物业的内容。请考虑以下两种情况:
场景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:您编写了一种操作底层数据的方法。一个很好的例子就是序列化。您可能希望序列化基础数据成员,而不是属性访问器返回的值。
答案 2 :(得分:1)
取决于,如果您访问该属性,可能会调用“验证”代码。
private int timeSinceLastPropertyAccess;
public int TimeSinceLastPropertyAccess
{
get
{
// Reset timeSinceLastPropertyAccess to 0
int a = timeSinceLastPropertyAccess;
timeSinceLastPropertyAccess = 0;
return a;
}
}
你想让timeSinceLastPropertyAccess在课堂内使用时重置吗?
答案 3 :(得分:1)
只是添加一件事,你的例子只询问了吸气剂。另一半是制定者。
有时您会希望对象使用setter,有时您会希望它绕过它们并只分配底层字段。
例如,假设您有一个名为IsModified的属性。无论何时修改对象,都会告诉您。如果为其中一个基础字段分配了不同的值,您可以让所有的setter将其翻转为true。
现在,如果您正在为该对象提供保湿(从db或其他地方加载),那么您不希望设置IsModified。因为,坦率地说,它还没有被修改。因此,在该方法中,您使用基础字段名称,但在所有其他方法中,您使用属性设置器。
答案 4 :(得分:0)
这取决于,你想做房产的事吗?私人/公共并不重要,就像调用一个函数一样。
实际上,你实际上只是设置了一个“功能”,以期在访问或更改该值时必须做某事。
这样做的问题是你可能会发现你想在某些地方做一件事,而在另一些地方访问另一件事,所以你仍然要改变所有的'电话'在其中一个地方。
事实上,如果访问该变量的一切 - 甚至是私有类函数 - 通过刚刚通过变量的属性来实现,那为什么还要打扰这个属性呢?为什么不只是创建一个名为'MyVariable'的变量,然后如果你发现你想要改变/访问它时做一些事情,只需创建一个名为_MyVariable或其他的变量,然后将MyVariable更改为_MyVariable的属性。
你应该认为属性就像你曾经写过的accessor()和mutator()函数一样,如果你发现你想要在“访问”变量时想要做一些代码,那么它们的技巧就是您必须更改对该变量的所有调用以使用访问器(调用函数,而不是仅访问成员变量),这就是为什么您将创建“默认”访问器和matadors,以防万一。正如我上面所说,你没有c#和属性的问题(除非在一个蹩脚的情况下你不能写成员的子成员,如果它的属性......为什么?)