这个问题是为了寻找匈牙利表示法的好例子,这样我们就可以收集这些例子。

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

有帮助吗?

解决方案 2

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

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

其他提示

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

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

  • 字符串名字 - 这可能只是 因为它的用途很明显,所以类型并不那么重要,在这种情况下应该很明显。如果不明显,IDE 可以帮助您。
  • txt名字 - 这可以更改为 名字文本框 或者 名字_文本框. 。它读起来更好,而且您知道它是一个控件而不仅仅是文本。
  • 账户 - C 在 MFC 中用于类名,但您实际上并不需要它。 帐户 就足够好了。大写名称是类型的标准约定(它们仅出现在特定位置,因此不会与属性或方法混淆)
  • ixArray (索引到 大批) - ix 有点晦涩难懂。尝试 数组索引.
  • 美国州 (不安全字符串 状态) - 看起来像“美国状态”。最好一起去 状态_不安全字符串 或者其他的东西。甚至可能把它包裹在一个 不安全字符串 类至少使其类型安全。

p

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

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

t

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

使用匈牙利语来指示类型是没有意义的,因为编译器已经为您完成了。

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

dxHighlight = xStart - xEnd

yHighlight = yLocation + 3

yEnd = yStart + dyHeight

dyCode = dyField * 2

等等。它很有用,因为您可以一目了然地发现错误:如果将 dy 添加到 y,则始终会得到 y。如果你减去两个 x,你总是得到一个 dx。如果将 dy 乘以标量,则始终会得到 dy。等等。如果您看到类似这样的行

yTop = dyText + xButton

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

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

我们用:

n: Number 
p: Percentage 1=100% (for interest rates etc)
c: Currency
s: String
d: date
e: enumeration
o: object (Customer oCustomer=new Customer();)
...

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

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

它是一个救星。

魔鬼代言人:匈牙利表示法最好的例子就是不要使用它。:D

在现代 IDE 中使用匈牙利表示法并没有获得任何优势,因为它们知道类型。它在重构变量的类型时增加了工作量,因为名称也必须更改(并且大多数时候,当您处理变量时,您无论如何都知道它是什么类型)。

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

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

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

当您继承一个软件项目时,匈牙利表示法(驼峰命名法,据我所知)是非常宝贵的。

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

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

我强烈反对匈牙利表示法,直到我真正开始阅读它并试图理解它的初衷。
在阅读了 Joels 的文章“错误”和文章“重新发现匈牙利表示法”后,我真的改变了主意。如果做得正确的话,我相信它一定非常强大。

乔尔·斯波尔斯基错了
http://www.joelonsoftware.com/articles/Wrong.html

重新发现匈牙利表示法
http://codingthriller.blogspot.com/2007/11/rediscovering-hungarian-notation.html

我相信大多数反对者从未真正尝试过,也没有真正理解它。我很想在实际项目中尝试一下。

我认为从上面链接的 Joel 的文章以及一般的匈牙利表示法中学到的关键是,当变量存在不明显的情况时使用它。

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

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

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

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

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

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

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

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

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

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

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

我认为匈牙利语旨在作为变量名称的补充,而不是信息的替代品。而且,很多时候匈牙利表示法根本不会增加变量的可读性,浪费字节和读取时间。

只是我的2美分。

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

我的

对于局部变量,区分名称在全局上下文中可能有意义的位置。如果您看到 myFoo,则它仅在此函数中使用,而不管我们在其他任何地方对 Foos 执行的任何其他操作。

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

tmp

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

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

有时 老的新的 出于类似的原因 tmp, ,通常在较长的循环或函数中。

我只使用 p 作为指针,仅此而已。这只是当我使用 C++ 时。在 C# 中,我不使用任何匈牙利表示法。例如

MyClass myClass;
MyClass* pMyClass;

就这样 :)

编辑: 哦,我刚刚意识到这是一个谎言。我也使用“m_”作为成员变量。例如

class
{
private:
bool m_myVar;
}

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

没有匈牙利表示法的好例子。只是不要使用它。即使您使用的是弱类型语言也不会。你会生活得更幸福。

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

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

我发现自己使用表示“工作”的“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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top