好的,一个简单的问题。
首先,我必须说我的关注不是性能。我完全清楚,无论一个选项或另一个选项可能带来什么样的性能成本都可能毫无意义,甚至在正常情况下都不值得考虑。它更多地与设计标准和好奇心有关,大多数编码人员会如何做到这一点。
好的,问题很简单:
假设我有一个 ComplexNumber struct
,我可以通过以下方式实现:
public struct Complex : IEquatable<Complex>, IFormattable
{
readonly double realPart, imaginaryPart, magnitude, argument;
readonly static Complex j = new Complex(0, 1);
public Complex(double realPart, double imaginaryPart)
{
this.realPart = realPart;
this.imaginaryPart = imaginaryPart;
this.magnitude = Math.Sqrt(Math.Pow(realPart, 2) + Math.Pow(imaginaryPart, 2));
this.argument = Math.Atan2(imaginaryPart, realPart);
}
public double RealPart { get { return this.realPart; } }
public double ImaginaryPart { get { return this.imaginaryPart; } }
public double Magnitude { get { return this.magnitude; } }
public double Argument { get { return this.argument; } }
public static Complex J { get { return Complex.j; } }
...
}
Magnitude
和Argument
属性具有在构造时评估的支持字段。另一种选择是简单地评估任何一个getter中的相应值。
最推荐的方法是什么?是否有任何编码标准为了有标准而推荐任何选项?如果没有,通常首选的是什么?或者它只是性能依赖,在我的情况下是无关紧要的?
答案 0 :(得分:1)
[更新如下:]
为什么要在吸气剂中而不是在定位器中进行评估?我会评估它的设置值。这样,正确的值可以在私有方法中使用。
在c'tor中设置默认值,在setter中进行评估。
您将始终比设置更频繁地阅读该值,因此出于性能原因,您应该在设置器中进行评估 - 它的运行频率会降低。
[UPDATE:] 如果该属性是只读的,则在c'tor中进行评估,其结果与上述相同(性能 - 您只需进行一次评估)。我知道你说性能不是问题,但如果没有理由不以更好的方式做到这一点,那么应该这样做。
答案 1 :(得分:1)
我倾向于直接在getter中计算值,因为它更具可读性:如果你想知道Argument
做什么,只需看看它的代码。如果您像现在一样在字段中缓存值,则必须转到Argument
属性→argument
字段→构造函数。
如果性能确实很重要,那么在您的情况下找出哪个选项更好的正确方法就是分析。但是作为一个 guess ,我认为在字段中缓存值的版本也会变慢,特别是如果你不经常使用计算值。这是因为struct
一直在被复制,而这些字段使struct
的两倍大。
答案 2 :(得分:0)
C'tor
应使用默认值初始化成员。
当然,如果将代码移动到getter,性能可能会成为问题,因为每次调用getter时都会对其进行评估。
然而,吸气者的合同说它会得到价值。所以在吸气剂阻滞中应尽可能避免计算部分。
您还应该尽量避免使用脏值。如果你在getter中设置Magnitude
(比如说),但是尝试直接在类中访问它;你可能最终会使用错误的价值。
因此,如果问题是关于初始化成员变量,请在c'tor中进行。这就是为什么它是由语言设计师创造的。