16

这个问题是为了寻找匈牙利符号的好例子,所以我们可以把这些集合在一起。

编辑:我同意匈牙利语的类型不是那么必要,我希望有更具体的例子来增加可读性和可维护性,就像乔尔在他的文章中给出的那样(根据我的回答)。

4

22 回答 22

40

要求匈牙利符号的好例子的问题是每个人都会对一个好例子的样子有自己的想法。我个人认为最好的Hungarian Notationno Hungarian Notation。该符号最初旨在表示变量的预期用途而不是其类型,但它通常用于类型信息,特别是用于表单控件(例如,txtFirstName用于表示某人名字的文本框。)。这使得代码在可读性(例如,“prepIn nounTerms prepOf nounReadability”)和需要更改类型时的重构(Win32 API 中的“lParams”已更改类型)方面的可维护性降低。

您可能应该考虑根本不使用它。例子:

  • strFirstName - 这可以只是firstName,因为它的用途很明显,类型并不那么重要,在这种情况下应该很明显。如果不是很明显,IDE 可以帮助您。
  • txtFirstName - 这可以更改为FirstNameTextBoxFirstName_TextBox。它读起来更好,你知道它是一个控件,而不仅仅是文本。
  • CAccount - C用于 MFC 中的类名,但你真的不需要它。帐户足够好。大写名称是类型的标准约定(它们只出现在特定位置,因此不会与属性或方法混淆)
  • ixArray数组的索引) -ix有点晦涩。试试arrayIndex
  • usStateState的不安全字符串)- 看起来像“US State”。最好使用状态_UnsafeString或其他东西。甚至可能将其包装在UnsafeString类中,以至少使其类型安全。
于 2008-10-14T17:48:14.550 回答
28

正如其他匈牙利帖子中提到的那样,现在经典的文章来自 Joel 的网站:

http://www.joelonsoftware.com/articles/Wrong.html

于 2008-10-14T17:38:38.640 回答
17

p

(用于指针)。它几乎是我使用的唯一前缀。我认为它为变量增加了很多(例如,它是一个指针),因此应该更加尊重地对待它。

匈牙利语的数据类型有点过时了,现在 IDE 可以告诉你类型是什么(只需几秒钟将鼠标悬停在变量名上),所以它并不那么重要。但是将指针视为其数据不好,因此您要确保即使用户在编码​​时做出不应该假设的假设,它对用户来说也是显而易见的。

于 2008-10-14T17:45:57.410 回答
15

受污染的数据。为从不受信任的来源传入的所有数据添加前缀,以使该变量受到污染。在对其进行任何实际工作之前,应清理所有受污染的数据。

于 2008-10-14T17:57:42.613 回答
9

用匈牙利语来表示类型是没有意义的,因为编译器已经为你做了。

匈牙利语的有用之处在于区分具有相同原始类型的逻辑不同类型的变量。例如,如果您使用整数来表示坐标,您可以在 x 坐标前面加上 x,在 y 坐标前面加上 y,在距离前面加上 d。所以你会有看起来像的代码

dxHighlight = xStart - xEnd

yHighlight = yLocation + 3

yEnd = yStart + dyHeight

dyCode = dyField * 2

等等。它很有用,因为您可以一眼就发现错误:如果您将 dy 添加到 ay,您总是会得到一个 y。如果你减去两个 x,你总是得到一个 dx。如果你将一个 dy 乘以一个标量,你总是得到一个 dy。等等。如果你看到像这样的线

yTop = dyText + xButton

你一眼就知道这是错误的,因为添加 dy 和 ax 没有意义。编译器无法为您捕捉到这一点,因为据它所知,您正在将一个 int 添加到一个 int 中,这很好。

于 2008-11-30T05:52:00.843 回答
6

不要使用特定于语言的前缀。

我们用:

n:数字
p:百分比 1=100%(用于利率等)
c:货币
s:字符串
d:日期
e:枚举
o:对象(客户 oCustomer=新客户();)
...

我们对所有语言使用相同的系统:

SQL
C
C#
Javascript
VB6
VB.net
...

这是一个救生员。

于 2008-11-29T08:04:24.633 回答
5

Devil's Advocate:匈牙利符号的最好例子就是不要使用它。:D

在现代 IDE 中使用匈牙利符号没有任何优势,因为它们知道类型。它在重构变量的类型时增加了工作,因为名称也必须更改(并且大多数情况下,当您处理变量时,您知道它是什么类型)。

您还可以使用该符号解决排序问题。如果您使用 p 表示指针,a 表示地址,您是调用变量 apStreet 还是 paStreet?当你没有一致性时,可读性会降低,当你必须记住你必须写符号的顺序时,你必须占用宝贵的大脑空间。

于 2008-10-14T17:49:41.380 回答
5

我发现匈牙利符号有时在动态语言中很有用。我特别想到了服务器端 Actionscript(基本上只是 javascript),但它可以应用于其他地方。由于根本没有真正的类型信息,匈牙利符号有时可以帮助使事情更容易理解。

于 2008-10-14T17:51:48.723 回答
4

唯一真正有用的匈牙利语是 m_ 用于成员变量。(我也将 sm_ 用于静态成员,因为那是仍然存在的“其他”范围。)对于采用 80 亿字符长变量名称的宽屏监视器和编译器,缩写类型名称是不值得的。

于 2008-10-14T18:17:08.500 回答
4

当你继承一个软件项目时,匈牙利符号(骆驼式,据我所知)是非常宝贵的。

是的,您可以使用 IDE 将“悬停”在一个变量上并找出它是什么类,但是如果您正在翻阅数千行代码,您不想在这几秒钟内停下来 - 每...... ..单身....时间....

记住——你不是为你自己或你的团队单独编写代码。您还为那些必须在 2-5 年后拾取此代码并对其进行增强的人编写它。

于 2008-10-14T18:18:31.773 回答
4

I was strongly against Hungarian notation until I really started reading about it and trying to understand it's original intent.
After reading Joels post "Wrong" and the article "Rediscovering Hungarian Notation" I really changed my mind. Done correct I belive it must be extremly powerful.

Wrong by Joel Spolsky
http://www.joelonsoftware.com/articles/Wrong.html

Rediscovering Hungarian Notation
http://codingthriller.blogspot.com/2007/11/rediscovering-hungarian-notation.html

I belive that most Naysayers have never tried it for real and do not truly understand it. I would love to try it out in a real project.

于 2010-09-08T12:27:03.363 回答
3

我认为从上面链接的 Joel 的文章和一般的匈牙利符号中带走的关键是在变量有一些不明显的地方时使用它。

文章中的一个示例是编码字符串与非编码字符串,并不是说您应该将匈牙利语“us”用于不安全字符串,将“s”用于安全字符串,而是您应该有一些标识符来指示字符串是安全的或不。如果它成为标准,则很容易看出标准何时被打破。

于 2008-10-14T18:55:08.363 回答
2

使用 ORM(例如休眠)时,您倾向于处理托管和非托管对象。更改托管对象将反映在数据库中,而无需调用显式保存,而处理托管对象需要显式保存调用。您处理对象的方式将根据对象的不同而有所不同。

于 2008-10-14T18:02:04.070 回答
2

我发现唯一有用的一点是在声明界面控件时,txtUsername、txtPassword、ddlBirthMonth。它并不完美,但它有助于大型表单/项目。

我不将它用于变量或其他项目,仅用于控件。

于 2008-10-14T18:09:12.213 回答
2

除了使用“p”作为指针之外,我还喜欢使用“cb”和“cch”来指示缓冲区大小参数(或变量)是字节数还是字符数(我也见过 -很少 - 'ce' 用于表示元素的数量)。因此,前缀不是传达类型,而是传达用途或意图。

我承认,我没有像我应该的那样始终如一地使用前缀,但我喜欢这个想法。

于 2008-10-14T18:30:06.930 回答
2

我同意匈牙利符号不再特别有用。我以为它的初衷不是表示数据类型,而是表示实体类型。例如,在涉及客户、员工和用户名称的代码部分中,您可以命名本地字符串变量 cusName、empName 和 usrName。这将有助于区分听起来相似的变量名称。实体的相同前缀将在整个应用程序中使用。但是,当使用 OO 并且您正在处理对象时,这些前缀在 Customer.Name、Employee.Name 和 User.Name 中是多余的。

于 2008-10-14T20:33:45.340 回答
2

变量的名称应该描述它是什么。 良好的变量命名使匈牙利表示法毫无用处。

但是,有时除了良好的变量命名之外,您还会使用匈牙利符号。m_numObjects 有两个“前缀”:m_ 和 num。 m_表示范围:它是绑定到this的数据成员。 num表示值什么。

当我阅读“好”的代码时,我一点也不觉得受阻,即使它确实包含一些“匈牙利语”。对:我读代码,我不点击它。(事实上​​,在编码或任何特定于巫毒编程的查找功能时,我几乎不使用鼠标。)

当我阅读 m_ubScale 之类的内容时,我的速度变慢了(是的,我在看着你,Liran!),因为我必须查看它的用法(没有评论!)以找出它的缩放比例(如果有的话?)它是数据类型(恰好是定点字符)。更好的名称是 m_scaleFactor 或 m_zoomFactor,带有一个定点数的注释,甚至是 typedef。(事实上​​,typedef 会很有用,因为有几个类的其他几个成员使用相同的定点格式。但是,有些没有,但仍然标记为 m_ubWhatever!至少可以说令人困惑。)

我认为匈牙利语的目的是作为变量名的补充,而不是信息的替代品。此外,很多时候,匈牙利符号根本没有增加变量的可读性,浪费字节和读取时间。

只是我的2美分。

于 2008-11-30T06:54:35.397 回答
2

一个非常古老的问题,但这里有几个我经常使用的“匈牙利”前缀:

我的

对于局部变量,以区分名称在全局上下文中可能有意义的位置。如果你看到 myFoo,它只用在这个函数中,不管我们在其他任何地方用 Foos 做什么。

myStart = GetTime();
doComplicatedOperations();
print (GetTime() - myStart);

时间

用于循环或多步操作中值的临时副本。如果您看到两个 tmpFoo 变量相距超过几行,那么它们几乎肯定是不相关的。

tmpX = X; 
tmpY = Y;
X = someCalc(tmpX, tmpY);
Y = otherCalc(tmpX, tmpY);

有时出于与tmp类似的原因通常在更长的循环或函数中

于 2009-05-28T00:04:15.347 回答
1

我只使用 p 作为指针,仅此而已。只有当我使用 C++ 时。在 C# 中,我不使用任何匈牙利符号。例如

MyClass myClass;
MyClass* pMyClass;

就这样 :)

编辑:哦,我才意识到这是一个谎言。我也将“m_”用于成员变量。例如

class
{
private:
bool m_myVar;
}
于 2008-10-14T18:01:34.803 回答
1

好吧,我只将它与窗口控制变量一起使用。我使用 btn_、txt_、lbl_ 等来发现它们。我还发现通过键入控件的类型(btn_ 等)来查找控件的名称很有帮助。

于 2013-02-21T08:21:26.743 回答
0

没有匈牙利符号的好例子。只是不要使用它。即使您使用的是弱类型语言也不行。你会活得更快乐。

但是如果你真的需要一些理由不使用它,这是我最喜欢的一个,摘自 这个很棒的链接

匈牙利符号中的一个后续技巧是“更改变量的类型但保持变量名不变”。这几乎总是在 Windows 应用程序中完成,从 Win16 迁移:- WndProc(HWND hW, WORD wMsg, WORD wParam, LONG lParam) 到 Win32 WndProc(HWND hW, UINT wMsg, WPARAM wParam, LPARAM lParam) 其中 w 值提示它们是单词,但它们确实指的是多头。这种方法的真正价值随着 Win64 迁移而变得清晰,当参数将是 64 位宽时,旧的“w”和“l”前缀将永远保留。

于 2008-10-14T17:57:20.023 回答
0

我发现自己使用“w”表示“工作”,而不是“temp”或“tmp”作为前缀,用于存储数据的局部变量,例如:

Public Function ArrayFromDJRange(rangename As Range, slots As Integer) As Variant

' this function copies a Disjoint Range of specified size into a Variant Array 7/8/09 ljr

Dim j As Integer
Dim wArray As Variant
Dim rCell As Range

wArray = rangename.Value ' to initialize the working Array
ReDim wArray(0, slots - 1) ' set to size of range
j = 0

For Each rCell In rangename
    wArray(0, j) = rCell.Value
    j = j + 1
Next rCell

ArrayFromDJRange = wArray

End Function
于 2009-07-08T17:16:43.250 回答