C#编程规范(个人使用)

< DOCTYPE html PUBLIC -WCDTD XHTML StrictEN httpwwwworgTRxhtmlDTDxhtml-strictdtd>

1.1.1 类名、公开方法名、属性名使用Pascal 大小写形式;
例如:
  public class HelloWorld
  {
  void SayHello(string name)
  {
  ...
  }
  }
如果私有事件方法利用Visual Studio.Net产生,不用修改成Pascal 大小写形式。例如:buttonSave的事件方法private buttonSave_Click不用将首字母修改成大写ButtonSave_Click,因为它不是公开方法。
1.1.2 变量和方法参数使用Camel 大小写形式
  public class HelloWorld
  {
  int totalCount = 0;
  void SayHello(string name)
  {
  string fullMessage = "Hello " + name;
  ...
  }
  }

1.1.3 不要使用匈牙利方法来命名变量
  以前,多数程序员喜欢它-把数据类型作为变量名的前缀而m_作为成员变量的前缀。例如:
 string m_sName;
  int nAge;

  然而,这种方式在.NET编码规范中是不推荐的。所有变量都用camel 大小写形式,而不是用数据类型的缩写和m_来作前缀。
  表单变量(Form)、控件变量(如:TextBox, ComboBox ……)、和基本类型变量(如:int, long, string,……)可以用类型全称作为前缀。其它变量不用类型前缀。
用有意义的,描述性的词语来命名变量

1.1.4 应该用单词,不用缩写。别使用单个字母的变量像i, n, x 等,应该使用 index, temp等
例如:
好name, address, salary
不好nam, addr, sal

1.1.5 用于循环迭代的变量例外:允许使用单个字母的变量,例如i
     for ( int i = 0; i < count; i++ )
  {
  ...
  }

1.1.6 变量名中不使用下划线 (_) 。

1.1.7 名称空间需按照标准的模式命名,例如公司名.产品名,把微软的名称空间放在前面,随后是自定义的名称空间,最后是第三方的名称空间。

1.1.8 文件名要和类名匹配
例如,对于类HelloWorld, 相应的文件名应为 helloworld.cs (或, helloworld.vb)

1.1.9 缩进和间隔
缩进用 TAB,不用空格。

1.1.10 注释需和代码对齐。
  花括弧 ( {} ) 需和括号外的代码对齐。
  用一个空行来分开代码的逻辑分组。
  bool SayHello (string name)
  {
  string fullMessage = "Hello " + name;
  DateTime currentTime = DateTime.Now;
  string message = fullMessage + ", the time is : " + currentTime.ToShortTimeString();
MessageBox.Show ( message );

  if ( ... )
  {
  // Do something
  // ...
  return false;
  }
  return true;
  }

1.1.11 在一个类中,各个方法需用一空行,也只能是一行分开。

1.1.12 花括弧需独立一行,而不像if, for 等可以跟括号在同一行。即使只有一行的if语句也用花括弧。
  好:
  if   ( ... )
  {
   // Do something
  }
  不好:
  if ( ... ) {
  // Do something
}

1.1.13 空格要求:在每个运算符的前后都空一格;
方法调用的括号左右没有空格;
if、while、for和后面的左圆括号之间有一个空格,但是左圆括号之后没有空格;
分号左边没有空格
(这个例子用“&#9633;”表示空格)
好:
  if&#9633;(showResult&#9633;==&#9633;true)
{
string&#9633;message&#9633;=&#9633;" the time is : "&#9633;+&#9633;currentTime.ToShortTimeString();
MessageBox.Show(message);

  for&#9633;(int&#9633;i&#9633;=&#9633;0;&#9633;i&#9633;<&#9633;10;&#9633;i&#9633;++&#9633;)
  {
   //
  }
  }
  不好:
  if(showResult==true)
{
string message = " the time is : " + currentTime.ToShortTimeString();
MessageBox.Show&#9633;(&#9633;message&#9633;);
  for(int i= 0;i<10;i++)
  {
  //
  }
}

1.1.14 不要手工编辑Visual Studio.Net自动产生的代码;

1.1.15 不用提供public或protected成员变量,而是使用属性。

1.1.16 避免显式类型转换。使用as算法防护性地转换类型。
        Dog dog = new GermanShepherd();
        GermanShepherd shepherd = dog as GermanShepherd;
        if(shepherd != null)
        {...}

1.1.17 总是使用从0开始的数组。

1.1.18 类成员有委托时,调用前始终检查委托是否为空。
        public class MySource
        {
           public event EventHandler   MyEvent;
           public void FireEvent()
          {
             EventHandler temp = MyEvent;
             if (temp != null)
             {
                temp(this,EventArgs.Empty);
             }
          }
       }

1.1.19 总是使用一个for循环显式地初始化一个引用类型的数组。
      public class MyClass
      {}
      MyClass[] array = new MyClass[100];
      for(int index = 0; index < array.Length; index++)
      {
         array[index] = new MyClass();
      }

1.1.20 避免在布尔条件语句中调用函数。赋值到局部变量并检查它们的值。
      bool IsEverythingOK()
      {...}
      //不好:
      if(IsEverythingOK())
      {...}
      //好:
      bool ok = IsEverythingOK();
      if (ok)
      {
...
}

1.1.21 避免对只读变量使用const修饰符。在此情况下,采用readonly修饰符。
      public class MyClass
      {
         public readonly int Number;
         public MyClass(int someValue)
         {
            Number = someValue;
         }
         public const int DaysInWeek = 7;
      }

1.1.22 避免使用大文件。
如果一个文件里的代码超过300~400行,必须考虑将代码分开到不同类中。避免写太长的方法。一个典型的方法代码在1~25行之间。如果一个方法发代码超过25行,应该考虑将其分解为不同的方法。避免一个方法的参数超过5个,必要时使用对象(含多个属性)作为参数。(这一条不强求)

1.1.23 方法名需能看出它作什么。别使用会引起误解的名字。如果名字一目了然,就无需用文档来解释方法的功能了。
  好:
  void SavePhoneNumber ( string phoneNumber )
  {
  // Save the phone number.
  }

  不好:
  // This method will save the phone number.
  void SaveData ( string phoneNumber )
  {
  // Save the phone number.
}

1.1.24 一个方法只完成一个任务。不要把多个任务组合到一个方法中,即使那些任务非常小。
  好:
  // Save the address.
  SaveAddress (   address );
  
  // Send an email to the supervisor to inform that the address is updated.
  SendEmail ( address, email );  
  
  void SaveAddress ( string address )
  {
  // Save the address.
  // ...
  }
  
  void SendEmail ( string address, string email )
  {
  // Send an email to inform the supervisor that the address is changed.
  // ...
}

  不好:
  // Save address and send an email to the supervisor to inform that the address is updated.
  SaveAddress ( address, email );
  void SaveAddress ( string address, string email )
  {
  // Job 1.
  // Save the address.
  // ...
  // Job 2.
  // Send an email to inform the supervisor that the address is changed.
  // ...
  }

1.1.25 使用C#的特有类型,而不是System命名空间中定义的别名类型。
  好:
  int age;
  string name;
  object contactInfo;

  不好:
  Int16 age;
  String name;
Object contactInfo;

1.1.26 别在程序中使用固定数值,用常量代替。常量都用完全大写单词。

1.1.27 别用字符串常数。用资源文件。

1.1.28 避免使用很多成员变量。
声明局部变量,并传递给方法。不要在方法间共享成员变量。如果在几个方法间共享一个成员变量,那就很难知道是哪个方法在什么时候修改了它的值。

1.1.29 必要时使用enum 。别用数字或字符串来指示离散值。
  好:
  enum MailType
  {
  Html,
  PlainText,
  Attachment
  }
  void SendMail (string message, MailType mailType)
  {
  switch (mailType)
  {
  case MailType.Html:
  // Do something
break;

  case MailType.PlainText:
  // Do something
break;

  case MailType.Attachment:
  // Do something
break;

  default:
  // Do something
  break;
  }
  }

  不好:
  void SendMail (string message, string mailType)
  {
  switch ( mailType )
  {
  case "Html":
  // Do something
  break;
  case "PlainText":
  // Do something
  break;
  case "Attachment":
  // Do something
  break;
  default:
  // Do something
  break;
  }
}

1.1.30 别把成员变量声明为 public 或 protected。都声明为 private 而使用 public/protected 的Properties.

1.1.31 不在代码中使用具体的路径和驱动器名。 使用相对路径,并使路径可编程。
永远别设想你的代码是在“C:”盘运行。你不会知道,一些用户在网络或“Z:”盘运行程序。

1.1.32 应用程序启动时作些“自检”并确保所需文件和附件在指定的位置。必要时检查数据库连接。出现任何问题给用户一个友好的提示。

1.1.33 如果需要的配置文件找不到,应用程序需能自己创建使用默认值的一份。如果在配置文件中发现错误值,应用程序要抛出错误,给出提示消息告诉用户正确值。

1.1.34 错误消息需能帮助用户解决问题。永远别用像"应用程序出错", "发现一个错误" 等错误消息。而应给出像 "更新数据库失败。请确保登陆id和密码正确。" 的具体消息。

1.1.35 显示错误消息时,除了说哪里错了,还应提示用户如何解决问题。不要用 像 "登录失败。"这样的,要提示用户怎么做:"登录失败。请确保登录名和密码正确。"

1.1.36 显示给用户的消息要简短而友好。但要把所有可能的信息都记录下来,以助诊断问题。

1.1.37 文件头注释要求:
/// <summary>
/// 登录验证WebService
/// </summary>
/// <history>
///   <date>2004-02-25</date>
///   <programmer>张三</programmer>
/// <document>第一次做成,参考《登录验证详细设计书》3.2.1WebService</document>
///   <date>2004-11-22</date>
///   <programmer>李四</programmer>
/// <document>修正一个安全漏洞,参考《系统安全设计书》1.2.5</document>
/// </history>

1.1.38 方法头注释要求:
/// <summary>
/// 从数据库验证用户名和密码
/// </summary>
/// <param name = "username">用户名</param>
/// <param name = "password">密码</param>
/// <returns>true表示成功,false表示失败</returns >
/// <history>
///   <date>2004-02-25</date>
///   <programmer>张三</programmer>
/// <document>第一次做成,参考《登录验证详细设计书》3.2.1WebService</document>
/// </history>
private bool CheckUserValidation(string username, string password)
{

}
如果使用了复杂的算法,应为程序配备良好的文档和充分的注释。在文件头或者方法头增加算法描述。

在软件版本变更或者修改其他同事的代码时候,如果需要删除,应该用注释,而不是直接删除;如果需要修改,应该先注释原始的代码,然后增加新代码;新增代码也必须注释;
同一版本debug自己的代码发现错误,则直接修改,不需要注释;
例如:原始代码
private bool CheckUserValidation(string username, string password)
{
string sqlText = string.Format(“Select top 1 * from tUser where fLoginName = {0}”, username);
MessageBox.Show(sqlText);

}
修改后的代码
private bool CheckUserValidation(string username, string password)
{
   // <modify>
// <date>2004-11-22</date>
// <programmer>李四</programmer>
   // <reason>
// 原始代码仅仅比较用户名,没有考虑密码。参考《登录验证详细设计书》3.2.1
// </reason>
   // <original>
  
// </original>
// <new>
string sqlText = string.Format(“Select top 1 * from tUser where fLoginName = {0} and fPassword = {1}”, username, password);
// </new>
// </modify>

// <delete>
// <date>2004-11-22</date>
// <programmer>李四</programmer>
// <reason>正式版本中不需要在服务器上提示消息框。</reason>
// <original>

// </original>
// </delete>

// <add>
// <date>2004-11-22</date>
// <programmer>李四</programmer>
// <reason>……</reason>
some new codes
// </add>
}

1.1.39 异常处理
    不要捕捉了异常却什么也不做。如果隐藏了一个异常,你将永远不知道异常到底发生了没有。
  发生异常时,给出友好的消息给用户,但要精确记录错误的所有可能细节,包括发生的时间,和相关方法,类名等。
  先捕捉特定的异常,后捕捉一般的异常。
例如:
private void ReadFromFile ( string fileName )
  {
  try
  {
  // read from file.
  }
  catch (FileIOException ex)
  {
  // log error.
  //   re-throw exception depending on your case.
throw ex;
}
catch   (Exception e)
   {
     // Catching general exception
    // log error.
    throw e
}
  }

  在开发版本中捕获一般异常,写入日志,然后抛出一般异常,让程序崩溃。这将帮助你在开发周期发现大多数的错误。
  不必每个方法都用try-catch。当特定的异常可能发生时才使用。比如,当你写文件时,处理异常FileIOException.
  别写太大的 try-catch 模块。如果需要,为每个执行的任务编写单独的 try-catch 模块。 这将帮你找出哪一段代码产生异常,并给用户发出特定的错误消息
  如果应用程序需要,可以编写自己的异常类。自定义异常不应从基类SystemException派生,而要继承于. IApplicationException。

posted @ 2007-10-15 11:40  netcorner  阅读(241)  评论(0编辑  收藏  举报