关于语言不可知:我为什么不使用“匈牙利表示法”?

Why shouldn't I use “Hungarian Notation”?

我知道匈牙利语指的是什么——给出变量、参数或类型的信息作为其名称的前缀。尽管在某些情况下这似乎是一个好主意,但每个人似乎都对这一点表示强烈反对。如果我觉得有用的信息正在被传授,为什么我不应该把它放在可以得到的地方呢?

另请参见:人们在现实世界中使用匈牙利命名约定吗?


vusing adjhungarian注释). vmakes nreading nCode adjdifficult。


大多数人使用的东西,在匈牙利的符号是错误的方式获得的结果。

由Joel Spolsky优秀文章读取错误错误代码:制作的外观。

在短,匈牙利符号前缀的名字与你的变量(字符串)(匈牙利type浴系统,因为它是无用的。

它是由匈牙利符号和其作者,你的变量名的前缀与ITS kind(乔尔的例子使用的安全或不安全的字符串:字符串的应用程序),它使用所谓的匈牙利和安切洛蒂仍然是有价值的。


乔尔错了,这就是原因。

他所说的"应用程序"信息应该编码在类型系统中。您不应该依靠翻转变量名来确保不会将不安全的数据传递给需要安全数据的函数。您应该将其设置为类型错误,这样就不可能这样做。任何不安全的数据都应具有标记为不安全的类型,这样就不能简单地将其传递给安全函数。要从不安全状态转换为安全状态,需要使用某种消毒功能进行处理。

乔尔所说的很多"种类"都不是种类,事实上,它们是种类。

然而,大多数语言所缺少的是一个类型系统,它具有足够的表现力来加强这种区别。例如,如果C有一种"强typedef"(其中typedef名称具有基类型的所有操作,但不能转换为基类型),那么许多这些问题就会消失。例如,如果你可以说,EDCOX1 OR 0表示引入一种新的EDCOX1,1,它不能转换成STD::String(因此可以参与过载分辨率等),那么我们就不需要愚蠢的前缀。

所以,关于匈牙利语是用于非类型事物的中心观点是错误的。它被用来输入信息。当然,类型信息比传统的C类型信息更丰富;它是类型信息,编码某种语义细节来指示对象的用途。但它仍然是类型信息,正确的解决方案始终是将其编码到类型系统中。将其编码到类型系统中是获得正确验证和执行规则的最佳方法。变量名只是不切掉芥末。

换句话说,目标不应该是"让错误的代码在开发人员看来是错误的"。它应该是"使错误的代码在编译器看来是错误的"。


我认为它把源代码搞得一团糟。

在强类型语言中,它也不会给您带来什么好处。如果您执行任何形式的类型不匹配tombuilery,编译器将告诉您有关它的信息。


人们只有在没有理解语言符号的用户定义的类型。在现代的功能性语言或面向对象的编码信息,你会对它的"孩子"的值小于或datatype舱而进入到变量名。

请参考上传一些文章。然而,他的成绩是VBScript的例子中,它不支持用户定义的类(至少很长一段时间)。在一个用户定义的类型的语言你会一样的问题的解决通过创建一htmlencodedstring型然后让一只接受这样的方法。在一statically编译型语言,想抓住任何编码的错误,你会得到一个A型dynamically运行时异常,但在任何情况你写作的保护对未编码的字符串。匈牙利notations只是原来的程序员在人类A型检测器,是一个更好的工作,这是通常由软件处理。

"乔尔在匈牙利的区别系统"和"软件"系统在匈牙利,匈牙利的"encodes内置类型int和float样,等等,和"应用程序"/"encodes匈牙利",这是更高级别的信息超过一元变量的机型,在面向对象的语言和现代的功能你可以创建用户定义的类型,所以没有D之间的istinction型和镰刀的"孩子"在这两个系统可以代表的类型和"应用程序"只是为"匈牙利为匈牙利的冗余系统。

在回答这样的问题:人们只会使用系统不安全的一部分分配在弱型语言,一个int变量a浮点值的系统会崩溃。匈牙利在60年代发明的符号是专门用于BCPL语言,a漂亮的低水平是不做任何类型的工作在所有。我认为任何语言在使用今天总有这个问题,但作为一个孩子生活在符号"货物崇拜编程。

应用意义如果你想努力工作,一个用户定义的类类型没有语言,VBScript或早期出现VB的遗留。因此,在早期版本的Perl和PHP)。再次,利用IT在现代语言是纯粹的货物崇拜。

在任何其他语言,匈牙利的只是丑陋的,多余的和脆弱的。它已经被重复的信息系统,从类型,你不应该重复自己。使用描述性的名字为变量的意图,本研究特异性的实例的类型。使用的编码类型和元信息的系统不变量是"幸运"或"类"类型的变量。。。。。。。。。

一般一个点的代码有错误的文章上传到错误的外观是一个很好的原则。然而,更好的防止在错误是当所有可能有错误代码是由编译器自动检测。


我的所有项目都使用匈牙利符号。当我处理100个不同的标识符名称时,我发现它非常有用。

例如,当我调用一个需要字符串的函数时,我可以键入"s"并点击控制空间,我的IDE将精确地显示前缀为"s"的变量名。

另一个好处是,当我为unsigned加前缀u,为signed int加前缀i时,我会立即看到以潜在危险的方式混合有符号和无符号的地方。

我不记得在一个75000行代码库中,由于将局部变量命名为与该类的现有成员变量相同的变量,导致错误(我和其他人也是)的次数。从那以后,我总是在成员前面加上"m_uu"

这是一个品味和经验的问题。在你试过之前不要敲它。


你忘了把这些信息包括在内的首要原因。这与你无关,程序员。这一切都与你离开公司2年或3年后走上这条路的人有关,他必须阅读这些东西。

是的,一个IDE会很快为您识别类型。但是,当您阅读一些长批的"业务规则"代码时,最好不要在每个变量上停顿,以了解它是什么类型。当我看到strusrid、intproduct或guiproductid之类的东西时,它会使"加速"时间更加容易。

我同意微软在某些命名约定上做得太过火了——我把它们归为"太多好事"一类。

只要你坚持使用命名约定,它们就是好东西。我已经阅读了足够多的旧代码,这些代码让我不断地回头查看许多类似命名的变量的定义,从而推动了"camel-casing"(在以前的工作中称之为"camel-casing")。现在我正在做一个工作,有成千上万行完全未注释的经典ASP代码和vbscript,这是一个噩梦,试图解决问题。


在一开始的神秘人物跟踪在每个变量的名字是不必要的和节目名称,变量本身没有足够的描述。最需要的语言变量在声明类型无论如何,这样的信息已经可用。

也有在那里的局势,维护,一个变量的类型需要改变。例如:如果一个变量被定义为描述_ 16 u16foo"需要对64位无符号,一个二维的事情要发生。

  • 你会走和改变每个变量名称(确保不与任何unrelated裤子变量相同的名称),或
  • 只是改变和不改变类型的名字,这只会导致混乱。

  • 乔尔·斯波斯基写了一篇很好的博客。http://www.joelonsoftware.com/articles/wrong.html基本上,当一个合适的IDE告诉你想要的类型时,它不会让你的代码更难阅读,如果你不记得的话,变量是什么。另外,如果你把代码划分得足够多,你就不需要记住变量是如何声明为三页以上的。


    现在范围不比类型更重要吗,例如

    1
    2
    3
    4
    5
    * l for local
    * a for argument
    * m for member
    * g for global
    * etc

    用现代技术重构旧代码,搜索和替换一个符号,因为你改变了它的类型是冗长的,编译器会捕捉到类型的变化,但往往不会捕捉到不正确的使用范围,明智的命名约定有助于这里。


    没有理由不正确使用匈牙利符号。它的不受欢迎是由于长期以来对匈牙利符号的错误使用的猛烈抨击,特别是在WindowsAPI中。

    在过去糟糕的日子里,在类似于IDE的东西出现之前(很可能你没有足够的空闲内存来在Windows下运行编译器,所以你的开发是在DOS下完成的),将鼠标悬停在一个变量名上并没有得到任何帮助。(假设你有一个鼠标。)你必须处理的是事件回调函数,在这个函数中,所有东西都以16位int(word)或32位int(long word)的形式传递给你。然后,您必须将这些参数强制转换为给定事件类型的适当类型。实际上,大部分API实际上都没有类型。

    结果,一个参数名如下的API:

    1
    2
    3
    4
    LRESULT CALLBACK WindowProc(HWND hwnd,
                                UINT uMsg,
                                WPARAM wParam,
                                LPARAM lParam);

    请注意,wparam和lparam的名称虽然非常糟糕,但实际上并不比将它们命名为param1和param2差。

    更糟的是,窗口3.0/3.1有两种类型的指针:近指针和远指针。例如,内存管理函数locallock的返回值是一个pvoid,但是globallock的返回值是一个lpvoid(长时间使用"l")。然后,这个糟糕的符号得到了扩展,使得一个长指针字符串作为前缀lp,以将其与一个简单的malloc'd字符串区分开来。

    毫不奇怪,有人反对这种事情。


    作为一个Python程序员,匈牙利符号很快就崩溃了。在python中,我不关心某个东西是否是字符串——我关心它是否可以像字符串一样工作(即,如果它有返回字符串的___str___()方法)。

    例如,假设foo是一个整数,12

    1
    foo = 12

    匈牙利表示法告诉我们,我们应该称之为ifoo或其他东西,以表示它是一个整数,以便稍后我们知道它是什么。除了在Python中,这不起作用,或者更确切地说,它没有意义。在Python中,我决定使用它时需要什么类型。我想要根绳子吗?如果我这样做:

    1
    print"The current value of foo is %s" % foo

    注意%s字符串。foo不是字符串,但%运算符将调用foo.___str___()并使用结果(假设它存在)。foo仍然是一个整数,但是如果我们需要一个字符串,我们会把它当作一个字符串来处理。如果我们想要一个浮点数,我们就把它当作浮点数。在动态类型语言(如python)中,匈牙利表示法是无意义的,因为在您使用它之前,什么类型的东西都不重要,如果您需要一个特定的类型,那么只要确保在使用它时将它强制转换为该类型(如float(foo))。

    注意,像php这样的动态语言没有这样的好处——php试图在后台根据几乎没有人记住的一组模糊规则做"正确的事情",这通常会意外地导致灾难性的混乱。在这种情况下,一些命名机制,如$files_count$file_name,是很方便的。

    在我看来,匈牙利符号就像水蛭。也许在过去它们是有用的,或者至少看起来是有用的,但是现在它只是大量额外的输入,而不是很多益处。


    人们可以不使用符号语言的编译时类型检查,它将允许开发者去提醒自己如何处理特定的变量是位置。它是我们研究绩效或行为。它应该被编码和readability物大多是A A键和编码风格。出于这个原因,它是非常困难的criticized许多开发者——人人都有相同的布线在脑。

    的编译时类型检查的语言,大多是无用的-它应该启动一个滚动线揭示的宣言和企业类型。如果你或你的全局变量的代码块的多跨度超过一屏的设计和reusability坟墓,你有问题。这样的一个批评是匈牙利符号允许开发者有浴室的设计和很容易带走它。这是可能的一个原因是hatered。

    在其他的手,甚至可以有下在编译时类型检查的语言将受益从匈牙利符号——void指针或句柄的Win32 API的。论文obfuscates的实际数据类型,有可能是一个使用匈牙利符号有功绩。然而,如果一个数据类型的CAN技术在建造时,为什么不使用适当的数据类型。

    总的来说,没有硬的原因不使用匈牙利表示法。它是一个物所喜欢,政策,和编码风格。


    IDE应该提供有用的信息。当IDE的技术不那么先进时,匈牙利人可能会有某种意义(不是很多,而是一些)。


    应用程序匈牙利语对我来说是希腊语——用一种很好的方式

    作为一名工程师,而不是程序员,我立即阅读了Joel关于匈牙利应用程序优点的文章:"让错误的代码看起来是错误的"。我喜欢匈牙利语的应用程序,因为它模仿了工程、科学和数学如何使用子脚本和超脚本符号(如希腊字母、数学运算符等)来表示方程和公式。以牛顿万有引力定律为例:首先是标准数学符号,然后是应用匈牙利伪代码:

    Newton's Universal law of gravity for Earth and Mars

    1
    frcGravityEarthMars = G * massEarth * massMars / norm(posEarth - posMars)

    在数学符号中,最突出的符号是那些表示存储在变量中的信息类型的符号:力、质量、位置矢量等。下标用第二小提琴来解释:什么位置?这正是Hungarian应用程序所做的;它告诉您存储在变量中的类型,然后详细说明——关于最接近的代码可以到达数学符号。

    显然,强类型可以解决Joel文章中的安全与不安全字符串示例,但您不会为位置和速度向量定义单独的类型;这两个类型都是大小为3的双数组,您可能对其中一个所做的任何操作都可能适用于另一个。此外,连接位置和速度(形成一个状态向量)或取它们的点积是完全有意义的,但可能不添加它们。键入将如何允许前两个操作并禁止第二个操作,并且这样的系统将如何扩展到您可能希望保护的每一个操作?除非你愿意在你的打字系统中编码所有的数学和物理。

    最重要的是,许多工程是用弱类型的高级语言(如matlab)或旧语言(如fortran 77或ada)完成的。

    所以,如果你有一个花哨的语言和IDE和应用程序,匈牙利语并不能帮助你忘记它——很多人显然都有。但对我来说,比起一个使用弱类型或动态类型语言的新手程序员,我更糟糕的是,我可以用匈牙利语的应用程序更快地编写更好的代码。


    我一直认为一个或两个前缀放在正确的位置不会有什么伤害。我想如果我能传授一些有用的东西,比如"嘿,这是一个接口,不要指望具体的行为",就像在IEnumerable中一样,我应该这样做。注释可以使事情变得杂乱无章,而不仅仅是一个或两个字符的符号。


    在大多数现代的IDE中,它都是极其多余和无用的,它们可以很好地使类型变得明显。

    另外——对我来说——看到Inti、StruserName等很烦人:()


    If I feel that useful information is being imparted, why shouldn't I put it right there where it's available?

    那谁在乎别人怎么想?如果你觉得它有用,那就用符号。


    我的经验是,这很糟糕,因为:

    1-然后,如果需要更改变量类型(即,如果需要将32位整数扩展到64位整数),则中断所有代码;

    2-这是无用的信息,因为类型已经在声明中,或者您使用的是动态语言,在这种语言中,实际类型首先不应该如此重要。

    此外,对于接受通用编程的语言(即某些变量的类型在编写函数时无法确定的函数)或动态类型系统(即在编译时甚至无法确定类型),如何命名变量?大多数现代语言都支持一种或另一种语言,即使形式有限。


    Joel Spolsky在制作错误代码错误的外观解释了什么大家都认为他是匈牙利表示法(AS)说他是匈牙利的电话系统),它的目的是什么(什么是电话应用程序(匈牙利)。向下滚动到我的浴室在匈牙利被讨论。

    基本上,整个系统是个毫无价值的人。它只是告诉你同样的事情,你的编译器和/或IDE想告诉你。

    你的应用程序告诉人们"意思是可变的,和可以是有用的。


    如果控件列表显示在您的IDE中按字母顺序排列的下拉列表中,这对于在窗体上命名控件(btnok、txtlastname等)是一个很有用的约定。


    乔尔的文章很棒,但似乎忽略了一个要点:

    匈牙利语使特定的"想法"(种类+标识符名称)独一无二,或者接近唯一,跨越代码库——甚至是非常大的代码库。

    这对于代码维护来说是巨大的。这意味着您可以使用好的ol'单行文本搜索(grep,findstr,'在所有文件中查找')查找每个提到的"想法"。

    当我们有了知道如何读取代码的IDE时,为什么这一点很重要?因为他们还不太擅长。这在一个小代码库中很难看到,但在一个大的问题上是显而易见的——当评论中提到"想法"时,XML文件、Perl脚本,以及源代码管理之外的地方(文档、wiki、错误数据库)。

    在这里,您必须小心一点——例如在C/C++宏中粘贴令牌。可以隐藏对标识符的提及。这种情况可以用编码约定,而且无论如何,它们只影响代码库。

    另外,关于使用类型系统和匈牙利语,最好两者都使用。如果编译器不为您捕获代码,您只需要错误的代码就可以出错。在很多情况下,让编译器捕捉是不可行的。但在可行的地方-是的,请改为这样做!

    但是,在考虑可行性时,一定要考虑拆分类型的负面影响。例如,在C中,用非内置类型包装"int"会产生巨大的后果。所以在某些情况下是有意义的,但不是所有情况下。


    我倾向于只将匈牙利符号与ASP.NET服务器控件一起使用,否则我发现很难确定表单上的控件是什么。

    获取此代码段:

    1
     

    如果有人能在不使用匈牙利语的情况下展示一种更好的方法来使用这组控件名,我会很想使用它。


    揭穿匈牙利符号的好处

    • 它提供了一种区分变量的方法。

    如果类型是区分一个值和另一个值的所有类型,那么它只能用于将一种类型转换为另一种类型。如果在类型之间转换的值相同,那么很可能应该在专用于转换的函数中进行转换。(我已经看到匈牙利的vb6剩余部分在所有方法参数上使用字符串,仅仅是因为它们无法弄清楚如何反序列化JSON对象,或者无法正确理解如何声明或使用可以为空的类型。)如果您有两个仅由匈牙利前缀区分的变量,并且它们不是从一个变量到另一个变量的转换,那么你需要和他们详细说明你的意图。

    • 它使代码更具可读性。

    我发现匈牙利符号让人们懒惰地使用变量名。他们有一些东西可以区分,他们觉得没有必要详细说明它的目的。这是您通常会在匈牙利标记代码与现代代码中发现的:ssql与groupselectsql(或者通常根本没有ssql,因为它们应该使用早期开发人员放入的ORM),svalue与formcollectionvalue(或者通常也没有svalue,因为它们恰好在mvc中,并且应该使用它的模型绑定功能)。Stype与PublishSource等。

    它不可读。我看到更多的stemp1,stemp2…源于任何一个比其他人加起来还要多的匈牙利VB6。

    • 它可以防止错误。

    这将是由于数字2,这是错误的。


    用大师的话说:

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

    像往常一样有趣的阅读。

    摘录:

    有人在某个地方读了Simonyi的论文,在那里他用了"type"这个词,认为他指的是类型,比如类,比如在类型系统中,比如编译器所做的类型检查。他没有。他非常仔细地解释了"类型"这个词的确切含义,但没有用。损害已经造成了。"

    但是匈牙利语的应用程序仍然有巨大的价值,因为它增加了代码的搭配,这使得代码更容易阅读、编写、调试和维护,最重要的是,它使错误的代码看起来是错误的。

    在阅读Joel关于软件的文章之前,请确保您有一些时间。:)


    几个原因:

    • 任何现代的IDE给你想在你的鼠标类型的变量是在变量。
    • 类型名称是最长的(想的方式是合理的httpclientrequestprovider)被用来作为前缀。
    • 进位类型信息不正确的信息,它只是paraphrasing声明的变量,而变量的目的是outlining(想听听myinteger vs.)。

    我不认为每个人都反对它。在没有静态类型的语言中,它非常有用。我绝对喜欢它用于提供类型中还没有的信息。像在C语言中一样,char*szname说变量将引用以空结尾的字符串——这在char*中不是隐式的——当然,typedef也会有所帮助。

    乔尔有一篇关于使用匈牙利语来判断变量是否是HTML编码的伟大文章:

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

    不管怎样,当匈牙利语被用来传递我已经知道的信息时,我倾向于不喜欢它。


    当然,当99%的程序员在某件事情上达成一致时,就会出现问题。他们之所以在这里达成一致,是因为他们中的大多数人从未正确使用过匈牙利符号。

    有关详细的论证,我建议你参考一篇关于这个主题的博文。

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


    我几乎是在匈牙利符号被发明的时候开始编码的,第一次我被迫在一个项目中使用它的时候,我讨厌它。

    过了一会儿,我意识到,当它做得好的时候,它确实有帮助,而这些天我喜欢它。

    但像所有美好的事物一样,它必须被学习和理解,正确地完成它需要时间。


    匈牙利符号被滥用了,特别是微软,导致前缀比变量名长,并且显示出它是非常严格的,特别是当您更改类型时(臭名昭著的lparam/wparam,win16中的不同类型/大小,win32中的相同)。

    因此,无论是由于这种滥用,还是它被万美元使用,都被认为是无用的。

    在我的工作中,我们用Java编写代码,但是创始人McMs来自MFC Word,所以使用类似的代码风格(对齐的括号,我喜欢这个!,大写到方法名,我习惯了,前缀如m_u到类成员(字段),s_u到静态成员等)。

    他们还说,所有变量都应该有一个显示其类型的前缀(例如,bufferedreader被命名为brdata)。这表明这是一个坏主意,因为类型可以改变,但名称后面没有,或者编码员在使用这些前缀时不一致(我甚至看到abuffer、proxy等!).

    就我个人而言,我选择了一些我认为有用的前缀,最重要的是B来给布尔变量加前缀,因为它们是我唯一允许像if (bVar)这样的语法的前缀(不使用将某些值自动转换为true或false)。当我用C编码时,我对分配了malloc的变量使用了一个前缀,作为提醒,稍后应该释放它。等。

    所以,基本上,我不拒绝这个符号作为一个整体,但采取了似乎适合我的需要。当然,在为某个项目(工作、开源)做贡献时,我只是在适当的地方使用约定!


    我认为整个美学方面的东西都被夸大了。如果这是最重要的事情,我们不会称自己为开发人员,而是图形设计师。

    我认为,一个重要的部分是你描述你的对象角色是什么,而不是它是什么。你不称自己为人类清洁工,因为在另一种情况下,你将不是最重要的人。

    出于重构的目的,它也非常重要:

    1
    public string stringUniqueKey ="ABC-12345";

    如果您决定使用一个guid而不是字符串,那么重构所有引用代码后,您的变量名会显得很愚蠢。

    或:

    1
    public int intAge = 20;

    把这个改成一个浮点数,你也会遇到同样的问题。等等。


    所以什么湖的时候你使用前缀的成员变量?


    我找不到链接,但我记得在某个地方读到过(我同意)避免使用匈牙利符号会产生更好的编程风格。

    在编写程序语句时,在调用它的方法之前,您不应该考虑"这个对象是什么类型",而是应该考虑"我想用它做什么"、"要向它发送什么消息"。

    有点模糊的概念需要解释,但我认为它是可行的。

    例如,如果将客户名称存储在变量customer name中,则不应该关心它是字符串还是其他类。更重要的是要想从这个对象中得到什么。您想让它打印()、getFirstName()、getLastName()、convertToString()等吗?一旦您将其作为字符串类的实例并将其视为理所当然,就限制了您自己和您的设计,因为您必须在代码的其他地方构建所需的所有其他逻辑。


    如果你不知道变量的类型而不被告知,你可能无论如何都不应该弄乱它。

    类型也可能不那么重要。如果你知道这些方法的作用,你就可以知道变量在做什么,然后你就知道程序在做什么。

    有时可能需要它;当类型很重要且声明不接近或无法轻松推断类型时。但它不应该被视为绝对的


    多年来,我在编程中使用匈牙利符号。除了一些视觉上的混乱和在我更改数据类型时更改前缀的任务之外,没有人能说服我其他的事情。直到最近,当我不得不在同一个解决方案中组合现有的C和VB.NET程序集时。

    结果:我必须将"fltsomevariable"传递给"sngsomevariable"方法参数。即使是在C和VB.NET中编程的人,它也让我措手不及,让我停顿了一会儿。(C和VB.NET有时使用不同的名称来表示相同的数据类型——例如float和single)。

    现在考虑一下:如果您创建一个可以从多种语言调用的COM组件怎么办?对于一个.NET程序员来说,vb.net和c_"转换"很容易。但是在C++或Java中开发的人呢?对于不熟悉C++的.NET开发人员来说,"DWSOMVIEVALILE"是否意味着什么?


    • 他们是个非常严重的眼痛
    • 您的IDE应该能够告诉您需要知道的关于变量类型的所有信息。
    • 好的名字(hn会阻碍)应该和你交流你需要知道的关于变量的所有其他信息。

    匈牙利是珍贵的,因为它的人物沐浴在从交换变量的名字是什么,什么类型的信息?

    第一所有A型,在强烈的语言,编译器会警告你,如果你做任何真正的愚蠢。

    第二,如果你相信在良好的modularized代码不要做太多的工作在任何一个变量的函数,你可能只是被用在上面的代码,他们已经找到你就有这样的类型)。

    第三,如果你有一个前缀指针P和C类,你真的很现代的IDE敲诈你的待办事项的能力特征的IntelliSense(你知道它是什么,当你guesses型类名的表征,特别是当它得到它,你可以进入它的条件和它打你?好的,如果你有一个C类的前缀,你总是有一个额外的至少1型)。