C#中的匈牙利符号

Jas*_*son 33 c# naming-conventions

在使用C#之前,C++是我的主要编程语言.匈牙利的符号深藏在我的心里.

我在C#做了一些小项目而没有阅读C#书或其他语言指南.在那些小型的c#项目中我使用了类似的东西

private string m_strExePath;
Run Code Online (Sandbox Code Playgroud)

直到我从SO读到的东西说:

不要使用匈牙利表示法.

所以为什么?我是唯一一个在我的C#代码中有m_strExePath或m_iNumber的人吗?

17 *_* 26 48

Joel Spolsky 在这个主题上有一篇非常好的文章.快速总结是在实践中使用了两种类型的匈牙利表示法.

第一个是"匈牙利系统",您可以使用前缀指定变量类型.像字符串"str"的东西.这几乎是无用的信息,特别是因为现代IDE会告诉你这种类型.

第二个是"Apps Hungarian",您可以使用前缀指定变量的用途.最常见的例子是使用"m_"来表示成员变量.如果正确完成,这可能非常有用.

我的建议是避免像瘟疫这样的"匈牙利系统",但绝对使用"有用的匈牙利应用程序".我建议阅读乔尔的文章.它有点长,但解释得比我好多了.

本文最有趣的部分是匈牙利符号的最初发明者Charles Simonyi创建了"Apps Hungarian",但他的论文被错误地解释了,因此创造了"匈牙利系统"的憎恶.

  • 当IDE可以告诉您某些内容是否为成员变量时,我在Apps Hungarian中没有看到这一点. (7认同)
  • 我有第2版,第18项是"努力完成和最小化的类接口",这与此无关. (3认同)

Gav*_*ler 32

在进行用户界面设计时,我发现维护匈牙利表示法非常有用.文本框,标签和下拉列表等项目更容易快速理解,并且通常会重复控制名称:

lblTitle = Label
txtTitle = TextBox
ddlTitle = DropDownList
Run Code Online (Sandbox Code Playgroud)

对我来说,更容易阅读和解析.否则,由于IDE的进步,特别是Visual Studio,匈牙利符号不适合.

此外,Joel on Software有一篇与匈牙利符号相关的优秀文章,题目是:使错误的代码看起来错误,这匈牙利符号提供了一些很好的论据.

  • 我不同意.我认为在这种情况下情况更糟,特别是当你进入名字较长的控件或3字母缩写与另一个控件的3字母缩写冲突时.我们改为使用TitleLabel或TitleTextBox或TitleDropDown等. (14认同)
  • 我仍然不同意.对描述性的简洁性几乎没有正当理由.变量名称应该只要它是必需的.m_lblName和theLabelThatHoldsSomeonesName之间有一个快乐的中间地带. (4认同)
  • @John:我完全同意.我们没有字符限制,我们应该使变量更好和可读. (3认同)
  • @Jeff&John - 仅仅因为我们没有字符限制并不意味着它应该被使用.较小的简洁变量>较长的表达变量 (3认同)
  • 我也是这样做的,我觉得这很有道理.通常情况下,您将从代码隐藏中处理控件,并且不会在那里声明对象,而是在某些标记中.我喜欢从代码隐藏中知道我正在使用的东西的类型,而不必查看标记:) (2认同)

Jon*_*eet 30

你不是唯一的人,但我会说这是相对不常见的.就个人而言,我不是匈牙利表示法的粉丝,至少在简单的意义上说,只是重述声明中已经存在的类型信息.("真正的"匈牙利符号的粉丝会解释它的区别 - 它从来没有让我感到困扰,但我可以看到他们的观点.如果你使用一个共同的前缀,比如长度单位与重量单位,你不会意外使用权重值分配长度变量,即使两者都可能是整数.)

但是,对于私人会员,您几乎可以按照自己的意愿行事 - 与您的团队达成一致意见.重要的是,如果您希望您的API适合.NET的其余部分,请不要在您的公共成员中使用匈牙利表示法(包括参数).

  • 不,变量名称不会改变效率或编译时间等.它们比其他任何东西都更能影响可读性.(哦,不同的公共成员只是通过大小写限制了从不区分大小写的语言(如VB)使用类型的能力.) (2认同)

Jus*_*ner 21

不,你不是唯一一个这样做的人.人们普遍认为,匈牙利符号并不是用C#命名事物的最佳方式(IDE处理匈牙利符号试图解决的问题).


jal*_*alf 13

任何语言,匈牙利符号都是一个可怕的错误.你也不应该在C++中使用它.为变量命名,以便了解它们的用途.不要将它们命名为IDE可以提供给你的重复类型信息,并且可能会改变(并且通常无关紧要.如果你知道某些东西是一个计数器,那么它是无论是int16,32还是无关紧要64.你知道它作为一个计数器,因此,任何在计数器上有效的操作都应该是有效的.X/Y坐标的相同参数.它们是坐标.如果它们是浮点数或者它们无关紧要双倍.知道一个值是否以重量,距离或速度为单位可能是相关的.它是浮点数并不重要.).

事实上,匈牙利的符号只是作为一种误解而出现的.发明者曾打算用它来描述一个变量的"概念"类型(它是一个坐标,一个索引,一个计数器,一个窗口?)

阅读他的描述的人认为通过"类型"他意味着实际的编程语言类型(int,float,零终止字符串,char指针)

那绝不是意图,这是一个可怕的想法.它复制了IDE可以更好地提供的信息,并且首先不是所有相关的信息,因为它鼓励您以尽可能低的抽象级别进行编程.

所以为什么?我是有唯一的人 m_strExePathm_iNumber在我的C#代码?

不,不幸的是.告诉我,exePath如果它不是一个字符串会是什么?作为代码的读者,为什么我需要知道它是一个字符串?知道它是可执行文件的路径是不够的?m_iNumber刚刚命名得很糟糕.是多少?它适用于什么?你刚刚告诉我两次它是一个数字,但我仍然不知道这个数字是什么意思.

  • 你需要什么类型的?当我编程时,我想知道变量*代表什么*,而不是它的类型.如果你的'exePath`是`FileInfo`类型,它的名字很糟糕,那么****就是你的问题.变量的名称表示它是路径,而不是实际文件.因此,当我使用它时,我希望它的行为类似于路径名,而不是像文件一样. (4认同)
  • IDE可以提供类型,但只有当我浪费一点时间在变量名称上方盘旋时:-)我宁愿能够一目了然地看到它...并为你的例子提供一个对应点:exePath可能是System.IO.FileInfo对象,它是文件路径的包装器,可以轻松访问常见的文件系统操作.老实说,我没有看到变量名前缀的危害.我发现它使代码检查和调试更容易. (3认同)

Jar*_*Par 10

你肯定不是唯一的人,但我希望你是一个下降趋势的一部分:)

匈牙利表示法的问题在于它试图通过命名约定来实现类型系统.这是非常有问题的,因为它是一个只有人工验证的类型系统.项目中的每个人都必须同意相同的标准集,进行严格的代码审查并确保为所有新类型分配适当且正确的前缀.简而言之,用足够大的代码库来保证一致性是不可能的.在这一点上没有一致性为什么你这样做?

此外,工具不支持匈牙利表示法.这似乎是表面上的愚蠢评论,但考虑重构.匈牙利命名约定系统中的每次重构都必须伴随大量重命名,以确保维护前缀.批量重命名容易受到各种微妙错误的影响.

而不是使用名称来实现类型系统,只需依赖类型系统.它具有自动验证和工具支持.较新的IDE可以更容易地发现变量的类型(智能感知,悬停提示等),并真正消除了匈牙利符号的原始愿望.


Pat*_*ers 6

匈牙利表示法的一个缺点是开发人员经常在早期编码期间更改变量的类型,这需要变量的名称也发生变化.

  • 同意,它确实增加了代码库的维护负担. (3认同)

klo*_*cks 5

除非你使用文本编辑器而不是VS IDE,否则匈牙利符号几乎没有价值,它会阻碍而不是提高可读性


Ste*_*eve 5

匈牙利符号的真正价值可以追溯到C编程和指针的弱类型性质.基本上,回到白天,跟踪类型的最简单方法是使用匈牙利语.

在像C#这样的语言中,类型系统会告诉您所有需要知道的内容,并且IDE以非常用户友好的方式向您呈现这一点,因此根本不需要使用匈牙利语.

至于不使用它的充分理由,有很多.首先,在C#中,就C++和其他许多因素而言,你经常创建自己的类型,那么"MyAccountObject"类型的匈牙利语是什么?即使您可以决定合理的匈牙利语符号,它仍然会使实际的变量名称稍微难以阅读,因为您必须在开始时跳过"LPZCSTR"(或其他).更重要的是维护成本,如果你开始使用List并更改为另一种类型的集合(我现在似乎做了很多事情)怎么办?然后,您需要重命名使用该类型的所有变量,这些变量都没有实际好处.如果你刚刚开始使用一个像样的名字,你就不必担心这个问题.

在你的例子中,如果你创建或使用一些更有意义的类型来保存路径(例如路径),那么你需要改变你m_strExePathm_pathExePath,这是一个痛苦,在这种情况下实际上并没有多大帮助.