MicrosoftC#编码要求规范

上传人:痛*** 文档编号:91688538 上传时间:2022-05-17 格式:DOC 页数:75 大小:350.50KB
返回 下载 相关 举报
MicrosoftC#编码要求规范_第1页
第1页 / 共75页
MicrosoftC#编码要求规范_第2页
第2页 / 共75页
MicrosoftC#编码要求规范_第3页
第3页 / 共75页
点击查看更多>>
资源描述
wordMicrosoft C#编码规X本文档描述了微软一站式代码示例库项目组所采纳的关于本地 C+ 和 .NET C# 和VB.NET代码的编程风格指导规X。鸣谢本文档的每一章节都应该感谢Dan Ruder- 微软Principal Escalation Engineer 。Dan 对本文档进展了斟字酌句的查阅,并根据其20余年的编程经验提供了大量的珍贵评论。我很荣幸能与他共事。我同样感谢微软的四位经理,感谢他们对该项目的一贯支持。他们是Vivian Luo,Allen Ding,Felix Wu和Mei Liang。同时,如果没有如下一站式代码示例库项目的关键成员的辛勤付出,本文档必定不会具有现在的技术深度以与完整度,我在这里要感谢他们:Hongye SunJie WangJi ZhouMichael SunKira QianLinda LiuAllen Chen Yi-Lun LuoSteven ChengWen-Jun Zhang本文档局部章节参考自一些微软产品组的编程规X。感谢他们的慷慨共享。本编程规X在不断改善。如果您发现某些最优实践或者话题并没有涵盖在本文档中,请告知我们一站式示例代码库项目组,以不断充实改善本文档。我期待着您的参与。J声明本编程规X文档以“如是提供,无论明示或暗示都不包含任何形式保证,但并不限制适用于特殊目的的默认担保。当您编写VC+/VC#/VB.NET 代码时,敬请参考或使用本文档。但是,我们希望您能通过onecodemicrosoft.告知我们您正在使用本文档,或给出任何改良建议。目录1概览1原如此和主旨1术语22通用编程规X3明确和一致3格式和风格3库的使用5全局变量5变量的声明和初始化6函数的声明和调用7语句8枚举9空格14大括号15注释17代码块263C+ 编程规X27编译器选项27文件和结构29命名规X30指针34常量34类型转换3536字符串37数组38宏39函数40结构体43类4450动态分配51错误和异常52资源清理55控制流584.NET 编码规X61类库开发设计规X61文件和结构61程序集属性61命名规X61常量65字符串65数组和集合67结构体69类70命名空间74错误和异常74资源清理77交互操作9071 / 751 概览本文档为一站式示例代码库项目组所使用的C+ 以与 .NET编码规X。该规X源自于产品开发过程中的经验,并在不断完善。如果您发现一些最优实践或者话题并没有涵盖在本文档中,请联系我们一站式示例代码库项目组,以不断充实完善本文档。任何指导准如此都可能会众口难调。本规X的目的在于帮助社区开发者提高开发效率,减少代码中可能出现的bug,并增强代码的可维护性。万事开头难,采纳一个不熟悉的规X可能在初期会有一些棘手和困扰,但是这些不适应很快便会消失,它所带来的好处和优势很快便会显现,特别是在当您接手他人代码时。1.1 原如此和主旨高质量的代码示例往往具有如下特质:1. 易懂 代码示例必须易读且简单明确。它们必须能展示出重点所在。示例代码的相关局部应当易于重用。示例代码不可包含多余代码。它们必须带有相应文档说明。2. 正确性 示例代码必须正确展示出其欲告知使用者的重点。代码必须经过测试,且可以按照文档描述进展编译和运行。3. 一致性 示例代码应该按照一致的编程风格和设计来保证代码易读。同样的,不同代码示例之间也应当保持一致的风格和设计,使使用者能够很轻松的结合使用它们。一致性将我们一站式示例代码库优良的品质形象传递给使用者,展示出我们对于细节的追求。4. 流行性 代码示例应当展示现行的编程实践,例如使用 Unicode,错误处理,防御式编程以与可移植性。示例代码应当使用当前推荐的运行时库和API函数,以与推荐的项目和生成设置。5. 可靠性 代码示例必须符合法律,隐私和政策标准和规X。不允许展示入侵性或低质的编程实践,不允许永久改变机器状态。所有的安装和执行过程必须可以被撤销。6. 安全性 - 示例代码应该展示如何使用安全的编程实践:例如最低权限原如此,使用运行时库函数的安全版本,以与SDL推荐的项目设置。合理使用编程实践,设计和语言特性决定了示例代码是否可以很好满足上述特性。本编程规X致力于帮助您创建代码示例以使使用者能够作为最优实践来效仿和学习。1.2 术语在整个文档中,会有一些对于标准和实践的推荐和建议。一些实践是非常重要的,必须严格执行,另一些指导准如此并不一定处处适用,但是会在特定的场景下带来益处。为了清楚陈述规X和实践的意图,我们会使用如下术语。一定请.该规X或实践在任何情况下都应该遵守。如果您认为您的应用是例外,如此可能不适用。该规X用于减少bug。一定不要.不允许应用该规X或实践。您应该.该规X和实践适用于大多数情况。该规X用于统一编程风格,保持一致和清晰的风格。您不应该.不应该应用该规X或实践,除非有合理的理由。您可以该标准和规X您可以按需应用。该规X可用于编程风格,但不总是有益的。2 通用编程规X这些通用编程规X适用于所有语言 它们对代码风格,格式和结构提供了全局通用的指导。2.1 明确性和一致性一定请确保代码的明确性,易读性和透明性。编程规X致力于确保代码是易懂和易维护的。没有什么胜于清晰、简洁、自描述的代码。一定请确保一旦应用了某编程规X,需在所有代码中应用,以保持一致性。2.2 格式和风格一定不要使用制表符。不同的文字编辑器使用不同的空格来生成制表符,这就带来了格式混乱。所有代码都应该使用4个空格来表示缩进。可以配置Visual Studio 文字编辑器,以空格代替制表符。您应该 限制一行代码的最大长度。过长的代码降低了代码易读性 。为了提高易读性,将代码长度设置为78列。假如78列太窄,可以设置为86或者90。Visual C# 示例:一定请在您的代码编辑器中使用定宽字体,例如 Courier New。2.3 库的使用一定不要引用不必要的库,包括不必要的头文件,或引用不必要的程序集。注重细节能够减少项目生成时间,最小化出错几率,并给读者一个良好的印象。2.4 全局变量一定请尽量少用全局变量。为了正确的使用全局变量,一般是将它们作为参数传入函数。永远不要在函数或类内部直接引用全局变量,因为这会引起一个副作用:在调用者不知情的情况下改变了全局变量的状态。这对于静态变量同样适用。如果您需要修改全局变量,您应该将其作为一个输出参数,或返回其一份全局变量的拷贝。2.5 变量的声明和初始化一定请在最小的,包含该局部变量的作用域块内声明它。一般,如果语言允许,就仅在使用前声明它们,否如此就在作用域块的顶端声明。一定请在声明变量时初始化它们。一定请在语言允许的情况下,将局部变量的声明和初始化或赋值置于同一行代码内。这减少了代码的垂直空间,确保了变量不会处在未初始化的状态。/ C#sample:string name = myObject.Name;int val = time.Hours;一定不要 在同一行中声明多个变量。推荐每行只包含一句声明,这样有利于添加注释,也减少歧义。例如 Visual C+示例,Good:CodeExample *pFirst = NULL; / Pointer of the first element.CodeExample *pSecond = NULL; / Pointer of the second element.Bad:CodeExample *pFirst, *pSecond;后一个代码示例经常被误写为:CodeExample *pFirst, pSecond;这种误写实际上等同于:CodeExample *pFirst;CodeExample pSecond;2.6 函数的声明和调用函数或方法的名称,返回值,参数列表可以有多种形式。原如此上应该都将这些置于同一行代码内。如果带有过多参数不能置于一行代码,可以进展换行:多个参数一行或者一个参数一行。将返回值置于函数或方法名称的同一行。例如,单行格式:/ C# function call sample:hr = DoSomeFunctionCallparam1, param2, param3;多行格式:/ C# function call sample:hr = DoSomeFunctionCallparam1, param2, param3, param4, param5;将参数列表置于多行代码时,每一个参数应该整齐排列于前一个参数的下方。第一个类型/参数对置于新行行首,并缩进一个制表符宽度。函数或方法调用时的参数列表同样需按照这一格式。/ C+ / C# sample:hr = DoSomeFunctionCall hwnd, param1, param2, param3, param4, param5;一定请将参数排序,并首先将输入参数分组,再将输出参数放置最后。在参数组内,按照能够帮助程序员输入正确值的原如此来将参数排序。比如,如果一个函数带有2个参数, “left 和 “right ,将 “left 置于 “right 之前,如此它们的放置顺序符合其参数名。当设计一系列具有一样参数的函数时,在各函数内使用一致的顺序。比如,如果一个函数带有一个输入类型为句柄的参数作为第一参数,那么所有相关函数都应该将该输入句柄作为第一参数。2.7 代码语句一定不要在同一行内放置一句以上的代码语句。这会使得调试器的单步调试变得更为困难。Good:/ C# sample:a = 1;b = 2;Bad:/ C# sample:a = 1; b = 2;2.8 枚举一定请 将代表某些值集合的强类型参数,属性和返回值声明为枚举类型。一定请在适宜的情况下尽量使用枚举类型,而不是静态常量或 “#define 值。枚举类型是一个具有一个静态常量集合的结构体。如果遵守这些规X,定义枚举类型,而不是带有静态常量的结构体,您便会得到额外的编译器和反射支持。Good:/ C# sample:publicenumColor Red, Green, BlueBad:/ C# sample:publicstaticclassColorpublicconst int Red = 0;publicconst int Green = 1;publicconst int Blue = 2;一定不要使用公开集合作为枚举 例如操作系统版本,您亲朋的某某。一定请为简单枚举提供一个0值枚举量,可以考虑将之命名为 “None。如果这个名称对于特定的枚举并不适宜,可以自行定义为更准确的名称。/ C# sample:publicenumpression None = 0, GZip, Deflate一定不要 Enum.IsDefined 来检查枚举X围。有2个问题。首先,它加载反射和大量类型元数据,代价极其昂贵。第二,它存在版本的问题。Good:/ C# sample:if c Color.Black | c 5 y = 0;Bad in All-In-One Code Framework samples:/ C+ / C# sample:if x 5 y = 0;您应该在即使是单行条件式的情况下也使用大括号。这样做使得将来增加条件式更简便,并减少制表符引起的歧义。Good:/ C+ / C# sample:if x 5 y = 0;Bad:/ C+ / C# sample:if x 5 y = 0;2.10 注释您应该使用注释来解释一段代码的设计意图。一定不要让注释仅仅是重复代码。Good:/ Determine whether system is running Windows Vista or later operating / systems major version = 6 because they support linked tokens, but / previous versions major version = 6 because they support linked tokens, but / previous versions major version = 6您应该将注释缩进为被其描述的代码的同一级。您应该在注释中使用首字母大写的完整的句子,以与适当的标点符号和拼写。Good:/ Intialize the ponents on the Windows Form.Initializeponent; Intialize the ponents on the Windows Form.InitializeponentBad:/intialize the ponents on the Windows Form.Initializeponent;intialize the ponents on the Windows FormInitializeponent2.10.1 内联代码注释内联注释应该置于独立行,并与所描述的代码具有一样的缩进。其之前需放置一个空行。其之后不需要空行。描述代码块的注释应该置于独立行,与所描述的代码具有一样的缩进。其之前和之后都有一个空行。举例:if MAXVAL = exampleLength/ Reprort the error. ReportErrorGetLastError;/ The value is out of range, we cannot continue.return E_INVALIDARG;当内联注释只为结构体,类成员变量,参数和短语句做描述时,如此内联注释允许出现在和实际代码的同一行。在本例中,最好将所有变量的注释对齐。class Examplepublic: .void TestFunction . do . while !fFinished; / Continue if not finished. private:int m_length; / The length of the examplefloat m_accuracy; / The accuracy of the example;您不应该在代码中留有过多注释。如果每一行代码都有注释,便会影响到可读性和可理解性。单行注释应该用于代码的行为并不是那么明显易懂的情况。如下代码包含多余注释:Bad:/ Loop through each item in the wrinkles arrayfor int i = 0; i IsNew & / Process if its a new wrinkle nMaxImpact GetImpact / And it has the biggest impact nMaxImpact = pWrinkle-GetImpact; / Save its impact for parison pBestWrinkle = pWrinkle; / Remember this wrinkle as well 更好的实现如下:Good:/ Loop through each item in the wrinkles array, find the Wrinkle with / the largest impact that is new, and store it in pBestWrinkle.for int i = 0; i IsNew & nMaxImpact GetImpact nMaxImpact = pWrinkle-GetImpact; pBestWrinkle = pWrinkle;您应该为那些仅通过阅读很难理解其意图的代码添加注释。2.10.2 文件头注释一定请为每一份手写代码文件参加文件头注释。如下为文件头注释:VC+ 和 VC# 文件头注释模板:/* Module Header *Module Name: Project: Copyright c Microsoft Corporation.This source is subject to the Microsoft Public License.See .microsoft./opensource/licenses.mspx#Ms-PL.All other rights reserved.THIS CODE AND INFORMATION IS PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.*/举例, /* Module Header *Project: CppUACSelfElevationCopyright c Microsoft Corporation.User Account Control UAC is a new security ponent in Windows Vista and newer operating systems. With UAC fully enabled, interactive administrators normally run with least user privileges. This example demonstrates how to check the privilege level of the current process, and how to self-elevate the process by giving explicit consent with the Consent UI. This source is subject to the Microsoft Public License.See .microsoft./opensource/licenses.mspx#Ms-PL.All other rights reserved.THIS CODE AND INFORMATION IS PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.*/2.10.3 类注释您应该为每一个重要的类或结构体作注释。注释的详细程度应该视代码的用户群而定。C# 和 VB.NET 使用 .NET 描述性 XML 文档化注释。当您编译.NET 项目,并带有 /doc 命令时,编译器会在源代码中搜索 XML 标签,并生成XML文档。C# 类注释模板:/ /举例, / NAME: class CodeExample/ DESCRIPTION: The CodeExample class represents an example of code, and / tracks the length and plexity of the example./class CodeExample .;/ The CodeExample class represents an example of code, and tracks / the length and plexity of the example./publicclassCodeExample .2.10.4 函数注释您应该为所有重要的Public或非Public函数作注释。注释的详细程度应该视代码的用户群而定。C# 和 VB.NET 使用 .NET 描述性 XML 文档化注释。在一般情况下,至少需要一个 元素,一个 元素和 元素。会抛出异常的方法应使用 元素来告知使用者哪些异常会被抛出。C# 函数注释模板:/ / / / /exception cref=/ / 举例,/*-FUNCTION: IsUserInAdminGroupHANDLE hTokenPURPOSE: The function checks whether the primary access token of the processbelongs to user account that is a member of the local Administratorsgroup, even if it currently is not elevated.PARAMETERS:hToken the handle to an access token.RETURN VALUE: Returns TRUE if the primary access token of the process belongs to user account that is a member of the local Administrators group. Returns FALSE if the token does not.EXCEPTION: If this function fails, it throws a C+ DWORD exception which contains the Win32 error code of the failure. EXAMPLE CALL: try if IsUserInAdminGrouphToken wprintf LUser is a member of the Administrators groupn; else wprintf LUser is not a member of the Administrators groupn; catch DWORD dwError wprintfLIsUserInAdminGroup failed w/err %lun, dwError; -*/ The function checks whether the primary access token of the process / belongs to user account that is a member of the local Administrators / group, even if it currently is not elevated./The handle to an access token/ Returns true if the primary access token of the process belongs to / user account that is a member of the local Administrators group. / Returns false if the token does not./ When any native Windows API call fails, the function throws a / Win32Exception with the last error code./任何调用失败会带来副作用的方法或函数,都需要清楚地在注释中交代那些副作用的后果。一般而言,代码在发生错误或失败时不应该有副作用。当出现副作用时,在编写代码时应该有清楚的理由。当函数没有输出参数,或者只有一些单纯作为输出参数的情况下,无需交代理由。2.10.5 将代码注释掉当您用多种方法实现某些任务时,将代码注释掉便是必须的。除了第一个方法,其余实现方法都会被注释掉。使用 -or- 来分隔多个方法。举例, / C+ / C# sample:/ Demo the first solution.DemoSolution1;/ -or-/ Demo the second solution./DemoSolution2;2.10.6 TODO 待办注释一定不要在已发布的代码示例中使用TODO 待办注释。每一个代码示例都必须完整,在代码中不能有未完成的任务。2.11 代码块一定请在大量代码会因为更具结构化而获益时,使用代码块声明。通过作用域或者功能性分类,将大量代码分组,会改善代码易读性和结构。C# 代码块:#region Helper Functions for XX.#endregion3 .NET 编码规X以下编程规X适用于C# 和。3.1 类库开发设计规XMSDN上的类库开发设计规X 对如何编写优秀的托管代码进展了细致的讨论。本章节的内容着重于一些重要的规X,以与一站式代码示例库对于该规X的一些例外情况。因此,建议你同时参照这两份文档。3.2 文件和结构一定不要在一个源文件内拥有一个以上的Public类型,除非它们只有泛型参数个数的差异,或者具有嵌套关系。一个文件内有多个内部类型是允许的。一定请以源文件所含的Public类名命名该文件。比如, MainForm 类应该在 MainForm.cs 文件内,而 List 类应该在 List.cs 文件内。3.3 程序集属性程序集应当包含适当的属性值来描述其命名,等等。将copyright设置为Copyright Microsoft Corporation 2010assembly: AssemblyCopyrightCopyright Microsoft Corporation 2010将Assemblypany 设置为 Microsoft Corporationassembly: AssemblypanyMicrosoft Corporation将AssemblyTitle 和 AssemblyProduct 设置为当前示例名assembly: AssemblyTitleCSNamedPipeClientassembly: AssemblyProductCSNamedPipeClient3.4 命名规X3.4.1 综合命名规X一定请为各种类型,函数,变量,特性和数据结构选取有意义的命名。其命名应能反映其作用。您不应该在标识符名中使用缩短或缩略形式的词。比如,使用 “GetWindow 而不是 “GetWin。对于公共类型,线程过程,窗口过程,和对话框过程函数,为“ThreadProc, “DialogProc, “WndProc 等使用公共后缀。 一定不要 使用下划线,连字号,或其他任何非字母数字的字符。 3.4.2 标识符的大小写命名规X如下表格描述了对不同类型标识符的大小写命名规X。类,结构体Pascal规X名词public class plexNumber .public struct plextStruct .命名空间Pascal规X名词一定不要 以一样的名称来命名命名空间和其内部的类型。namespace 枚举Pascal规X名词一定请以复数名词或名词短语来命名标志枚举,以单数名词或名词短语来命名简单枚举。FlagspublicenumConsoleModifiersAlt, Control方法Pascal规X动词或动词短语public void Print .public void ProcessItem .Public属性Pascal规X名词或形容词一定请以集合中项目的复数形式命名该集合,或者单数名词后面跟 “List 或者 “Collection。一定请以肯定短语来命名布尔属性, CanSeek ,而不是CantSeek。当以 “Is, “Can, or “Has 作布尔属性的前缀有意义时,您也可以这样做。publicstring CustomerNamepublic ItemCollection Itemspublic boolCanRead非Public属性Camel规X或_camel规X名词或形容词一定请在您使用_ 前缀时,保持代码一致性。privatestring name;privatestring _name;事件Pascal规X动词或动词短语 一定请用现在式或过去式来明确事件之前或是之后的概念。 一定不要 使用 “Before 或者“After 前缀或后缀来指明事件的先后。/ A close event that is raised after the window is closed.publicevent WindowClosed/ A close event that is raised before a window is closed.publicevent WindowClosing委托Pascal规X一定请为用于事件的委托增加EventHandler后缀。一定请为除了用于事件处理程序之外的委托增加Callback后缀。 一定不要 为委托增加 “Delegate 后缀。publicdelegate WindowClosedEventHandler接口Pascal规X,带有I 前缀名词publicinterfaceIDictionary常量Pascal规X用于Public常量;Camel规X用于Internal常量;只有1或2个字符的缩写需全部字符大写。名词publicconststring MessageText = A;privateconststring messageText = B;publicconst double PI= 3.14159.;参数,变量Camel规X名词int customerID;泛型参数Pascal规X,带有T 前缀名词一定请以描述性名称命名泛型参数,除非单字符名称已有足够描述性。一定请以T作为描述性类型参数的前缀。您应该 使用 T 作为单字符类型参数的名称。T, TItem, TPolicy资源Pascal规X名词一定请提供描述性强的标识符。同时,尽可能保持简洁,但是不应该因空间而牺牲可读性。一定请仅为命名资源使用字母数字字符和下划线。ArgumentExceptionInvalidName3.4.3 匈牙利命名法一定不要 例如,不要在变量名称内带有其类型指示符。3.4.4 户界面 控件命名规X用户控件应该使用如下前缀,其重要目的是使代码更易读。ButtonbtnCheckBoxchkCheckedListBoxlstboBoxcmbContextMenumnuDataGrid dgDateTimePickerdtpFormsuffix: XXXFormGroupBoxgrpImageListimlLabellbListBoxlstListViewlvwMenumnuMenuItemmnuNotificationIconnfyPanelpnlPictureBoxpct ProgressBarprgRadioButtonradSplittersplStatusBarstsTabControltabTabPagetabTextBox tbTimertmrTreeViewtvw比如,对于 “File | Save 菜单项选择线, “Save 菜单项应该命名为 “mnuFileSave。3.5 常量一定请将那些永远不会改变值定义为常量字段。编译器直接将常量字段嵌入调用代码处。所以常量值永远不会被改变,且并不会打破兼容性。publicclassInt32publicconstint MaxValue = 0x7fffffff;publicconstint MinValue = uncheckedint0x80000000;一定请为预定义的对象实例使用public static shared readonly字段。如果有预定义的类型实例,也将该类型定义为public static readonly。举例,publicclassShellFolderpublicstaticreadonlyShellFolder ProgramData = newShellFolderProgramData;publicstaticreadonlyShellFolder ProgramFiles = newShellFolderProgramData;.3.6 字符串一定不要使用 + 操作符中的& 来拼接大量字符串。相反,您应该使用StringBuilder 来实现拼接工作。然而,拼接少量的字符串时,一定请使用 + 操作符中的& 。Good:StringBuilder sb = newSt
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 管理文书 > 施工组织


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!