繁体   English   中英

不断滥用?

[英]Constant abuse?

我在一些具有以下常量的C#项目中遇到了一堆代码:

    const int ZERO_RECORDS = 0;
    const int FIRST_ROW = 0;
    const int DEFAULT_INDEX = 0;
    const int STRINGS_ARE_EQUAL = 0;

有没有人见过这样的东西? 有没有办法合理化使用常量来表示语言结构? IE:C#在数组中的第一个索引位于第0位。我认为如果开发人员需要依赖常量来告诉他们语言是0,那么就会出现更大的问题。

这些常量的最常见用法是处理数据表或“for”循环。

我是不是觉得这些是代码味道? 我觉得这些并不比以下更好:

const int ZERO = 0;
const string A = "A";

我是不是觉得这些是代码味道? 我觉得这些并不比以下更好:

比较以下内容:

if(str1.CompareTo(str2) == STRINGS_ARE_EQUAL) ...

if(str1.CompareTo(str2) == ZERO) ...
if(str1.CompareTo(str2) == 0) ...

哪个更直接?

滥用,恕我直言。 “零”只是其中的基础之一。

虽然STRINGS_ARE_EQUAL可能很简单,但为什么不“.Equals”?

接受限制使用魔法数字?

这肯定是代码味道。

意图可能是为代码添加“可读性”,但是在我看来这样的事情实际上会降低代码的可读性。

有些人认为程序中的任何原始数字都是“神奇的数字”。 我已经看到编码标准基本上说你不能只是把一个整数写入程序,它必须是一个const int。

我是不是觉得这些是代码味道? 我觉得这些并不比以下更好:

const int ZERO = 0;

const int A ='A';

可能有点嗅觉,但肯定比ZERO = 0和A ='A'好。 在第一种情况下,他们定义逻辑常量,即具有具体值实现的一些抽象概念(字符串相等)。

在您的示例中,您将定义文字常量 - 变量表示值本身。 如果是这种情况,我认为枚举是首选,因为它们很少是奇异值。

这是明确的错误编码。

我说常量应该只在需要的地方使用,以后某些事情可能发生变化。 例如,我有很多“配置”选项,如SESSION_TIMEOUT定义它应该保持不变,但也许它可以在以后调整。 我不认为ZERO可以在路上调整。

此外,对于幻数,不应包括零。

我觉得这个信念有点奇怪,因为我会说这样的事情会走得太远

//input is FIELD_xxx where xxx is a number
input.SubString(LENGTH_OF_FIELD_NAME); //cut out the FIELD_ to give us the number

你应该看看thedailywtf上的一些东西

One2Pt20462262185th

企业SQL

我认为有时人们会盲目地遵循“编码标准” ,即“不要使用硬编码值,将它们定义为常量,以便在需要更新时更容易管理代码” - 这对于以下内容来说是公平的:

const in MAX_NUMBER_OF_ELEMENTS_I_WILL_ALLOW = 100

但是没有意义:

if(str1.CompareTo(str2) == STRINGS_ARE_EQUAL)

因为每当我看到这段代码时,我需要搜索STRINGS_ARE_EQUAL定义的内容 ,然后检查文档是否正确。

相反,如果我看到:

if(str1.CompareTo(str2) == 0)

我跳过步骤1(搜索STRINGS_ARE...被定义为)并且可以检查规格0意味着什么值。

你会正确地想用Equals()替换它,并在你只对一个案例感兴趣的情况下使用CompareTo() ,例如:

switch (bla.CompareTo(bla1))
{
     case IS_EQUAL:
     case IS_SMALLER:
     case IS_BIGGER:
     default:
}

如果合适,使用if/else语句(不知道CompareTo()返回...)

我仍然会检查你是否根据规格正确定义了值。

这当然是不同的,如果规范定义像ComparisonClass::StringsAreEqual值或类似的东西(我刚刚做了一个)然后你不会使用0但适当的变量。

所以这取决于,当你特别需要访问数组中的第一个元素时, arr[0]arr[FIRST_ELEMENT]更好,因为我仍然会检查你所定义的FIRST_ELEMENT因为我不相信你,它可能是不同的东西比0 - 例如你的0元素是dud,真正的第一个元素存储在1 - 谁知道。

我会寻找代码味道。 如果需要这些常量,请将它们放入枚举中:

enum StringEquality
{
    Equal,
    NotEqual
}

(但我怀疑STRINGS_ARE_EQUALstring.Compare返回的string.Compare ,所以黑客返回枚举可能会更加冗长。)

编辑: SHOUTING_CASE也不是特别的.NET风格的命名约定

我不知道我是否会称它们为气味,但它们看起来似乎是多余的。 虽然DEFAULT_INDEX实际上可能有用。

重点是避免魔术数字和零并不是真正神奇的。

这个代码是你办公室里的东西还是你下载的东西?

如果它在办公室,我认为如果人们随机放置常量,这就是管理问题。 在全球范围内,除非每个人都清楚地了解或同意这些常数的用途,否则不应该存在任何常数。

理想情况下,在C#中,您需要创建一个包含每个其他类全局使用的常量的类。 例如,

class MathConstants
{
 public const int ZERO=0;
}

然后在后面的课程中,例如:

....
if(something==MathConstants.ZERO)
...

至少我是这样看的。 这样每个人都可以理解那些常数甚至没有阅读其他内容。 这会减少混乱。

使用常量我通常会想到四个原因:

  1. 作为可能在未来合理变化的值的替代(例如, IdColumnNumber = 1 )。
  2. 作为可能不易理解或有意义的值的标签(例如, FirstAsciiLetter = 65 ),
  3. 作为键入冗长或难以键入值的较短且不易出错的方式(例如, LongSongTitle = "Supercalifragilisticexpialidocious"
  4. 作为难以记忆的值的记忆辅助(例如, PI = 3.14159265

对于您的具体示例,以下是我如何判断每个示例:

const int ZERO_RECORDS = 0;
// almost definitely a code smell

const int FIRST_ROW = 0;
// first row could be 1 or 0, so this potentially fits reason #2,
// however, doesn't make much sense for standard .NET collections
// because they are always zero-based

const int DEFAULT_INDEX = 0;
// this fits reason #2, possibly #1

const int STRINGS_ARE_EQUAL = 0;
// this very nicely fits reason #2, possibly #4
// (at least for anyone not intimately familiar with string.CompareTo())

所以,我会说,不,这些并不Zero = 0A = "A"

如果零表示零以外的东西(在这种情况下为STRINGS_ARE_EQUAL)那么那就是神奇的。 为它创建一个常量是可以接受的,并使代码更具可读性。

创建一个名为ZERO的常量是毫无意义的,浪费手指能量!

闻到一点,但我可以看到这样的情况,特别是如果你有程序员一直从语言切换到语言。

例如,MATLAB是单索引的,所以我可以想象有人厌倦了在切换语言时犯下一个错误,并在C ++和MATLAB程序中定义DEFAULT_INDEX来抽象差异。 不一定优雅,但如果这是它需要...

对,你要问这个气味年轻的代码战士。 但是,这些命名常量来自于比Visual Studio更早出现的编码实践。 它们可能是多余的,但你可能比理解公约的起源更糟糕。 想想NASA电脑,回来的时候......

您可能会在跨平台情况下看到类似这样的内容,您可以将该文件与适合该平台的常量集一起使用。 但可能不是这些实际例子。 这看起来像COBOL编码器试图使他的C#看起来更像英语(没有针对COBOL编码器的冒犯)。

使用常量来表示抽象值是可以的,但用你自己的语言表示构造则是另一种。

const int FIRST_ROW = 0没有意义。

const int MINIMUM_WIDGET_COUNT = 0更有意义。

你应该遵循编码标准的假设是有道理的。 (也就是说,编码标准在组织内是推定正确的。)在不符合推定时严格遵循编码标准是没有意义的。

因此,我同意早期的海报,一些臭味常数可能是因为遵循编码标准(“无魔数”)而无例外。 这就是问题所在。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM