我在想,什么是好的做法:
private int value;
public int Value { get { return this.value; } }
private int DoSomething()
{
return this.Value + 1;
//OR
return this.value + 1;
}
所以,问题在于你应该如何对待你的类变量。您是应该通过您的房产访问它们还是直接访问它们?
答案 0 :(得分:8)
在这种情况下,它并不重要,但在你使用延迟加载变量的情况下,它很重要,你可以通过你的属性访问。例如:
private Myobject _value;
public Myobject Value
{
get
{
if (_value == null) _value = new MyObject();
return _value;
}
}
private MyObject DoSomething();
{
//If you access _value here, it might be null...
//so you should access it through the property:
return Value;
}
如果您的方法通过直接调用字段而失败,您可以正确处理它,也可以通过清理方法访问它 - 通过您的属性。
这一切都归结为您的应用程序的体系结构,因此您必须提出一个问题:从维护角度来看最有意义的是什么?
我不得不说,如果该字段已正确初始化并且不会让您直接访问它,那么请直接访问它。如果它导致额外的工作(以及额外的维护),那么引用该属性。
与其他任何事物一样,权衡利弊。使用你自己的常识 - 标准战争是一种荒谬的分心。除非他们为你提供你自己没有想过的论据,否则不要浪费你的气息。如果您有有效理由选择您选择的路径,那么该路径是正确的 - 它取决于设计师的特权。
我对利弊的看法是:
选择财产:
选择领域:
所以我猜我的方法是使用属性,除非我需要直接写入值,在这种情况下,我会选择字段 - 因为我的属性是只读的,因此无法写入。
这只是我 - 你的财产可能是读/写,你可以从设计的角度决定直接访问该领域是好的 - 这也没关系。
诀窍是 总是出于某种原因做事,不要因为盲目地做事。
答案 1 :(得分:2)
我会去直接访问。可以这么说,这就是“把它留在家里”。
答案 2 :(得分:1)
这是标准战已经被争夺的事情。通常它不会产生很大的不同,我决定直接从类内部访问变量,除了getter和setter之外,它们不仅仅是获取或设置值。
问题在于您必须知道getter和设置正在做什么,或者您必须始终将它们限制为简单操作而不需要其他功能。
答案 3 :(得分:1)
引入属性以“隐藏”最终比从字段返回单个值更复杂的结构。
我建议您在所有代码中使用属性而不是字段,因此如果属性代码稍后更改为更复杂的内容,则无需重构其余类。
答案 4 :(得分:0)
我投票支持返回this.value + 1。
针对此的论点(即通过属性进行)是您可能希望稍后在属性方法中添加额外的代码,因此如果您这样做,则会有更少的更改。但我的想法是,物业应该像宣传的那样做,而不是更多;也就是说,他们应该做足够的回报。
答案 5 :(得分:0)
在某些情况下,这是一个好主意。例如,对于iPhone,由于内存容量较小,您可能会从操作系统收到“内存警告”。根据这些警告,系统会要求您释放内存以避免被关闭。通常,这个内存来自图像,声音或大数据块等资源,而这些资源在内存中不需要连续使用。
在这种情况下,我有时通过Objective-C私有访问器访问一些私有ivars,它通常检查ivar是否为“nil”(NULL),并将数据加载到内存中,“延迟加载”,临时方式。为此,我发现私有财产非常有用。否则,我使用直接ivar访问。
与往常一样,我认为这个问题没有明确的答案:“这取决于”。
答案 6 :(得分:0)
如果你的类不能信任自己的方法来访问自己的私有变量,谁可以信任呢?
答案 7 :(得分:0)
我认为这不是一个黑白问题。我想到了一些事情:
首先,如果属性没有行为(即get / set只是通过获取并返回一个字段),那么将该字段变为自动属性并消除困境。更少的代码行,没有混乱。
其次,如果属性有副作用(延迟加载,更改通知,统计信息收集等),那么您必须考虑通过私有更新触发该行为是否合适。如果合适,只需使用该属性即可。如果它不合适则不要(或改变设计使其更明显)。
此外,在适当的情况下,如果非常重要,您可以始终引入包装类型以消除混淆。
E.g。假设您有一个受参数检查保护的Angle属性。
public class ManThatCanRotate
{
public int Angle
{
get { return m_angle; }
set { if(value >= 0 && value < 360) m_angle = value; }
}
public void RotateLikeSomeKindOfLunatic()
{
// imagine this has been called 359 times already.
m_angle++; // ruh-roh
}
}
如果你直接设置m_angle,就会发生坏事(tm);角度将变为无效。您可以简单地将角度重构为自己的类型,这样就无法使其无效,从而消除了问题。