C#程式中注釋過多的8條理由

來源:互聯網
上載者:User
文章目錄
  • 1  方法調用移動到新的類型中,原方法仍然保留在原來的類型中
  • 2  刪除不需要考慮的的條件或情況,因為怕考慮不充分而沒有刪除代碼
  • 3  因為考慮不周全,導致代碼中注釋與功能並存。保留注釋是為了出錯的情況下,協助分析代碼
  • 4  異常處理機制的改變,導致代碼中捕獲異常的代碼被注釋
  • 5  .NET架構的發展,導致一些代碼變成多餘但又沒有刪掉,先將其注釋
  • 6 運行環境的改變,注釋掉代碼以便於以後發現問題
  • 7  測試資料以注釋的方式,保留中代碼中,增加對代碼的解釋
  • 8  對每一個資料項目都進行注釋,必要的注釋和不必要的注釋混雜在一起

程式中中的注釋,一般是有益處的,可以知曉程式的一些邏輯說明,或是參數解釋。但是有些程式,因為注釋太多,反而引起維護上的不方便,刪掉了怕以後不能出現問題不好尋找原因,不刪除留在代碼中,對程式的維護人員,是一種痛苦。

以下列舉我可以理解的的原因,供分析參考。

1  方法調用移動到新的類型中,原方法仍然保留在原來的類型中
//public void ExecuteSqlCommand(string sqlCommandText)//{       //this.ExecuteSqlCommand(sqlCommandText, CommandType.Text, null);//}......
 

ExecuteSqlCommand方法已經被移植到新的輔助類型SqlHelper中,但是這裡的還沒有直接刪除。保留的目的,有可能存在反射調用,在報錯之後,看到這裡的代碼被注釋後,再才會重新尋找這片代碼的新的歸屬。

 

2  刪除不需要考慮的的條件或情況,因為怕考慮不充分而沒有刪除代碼
 static ClientProxyFactory()        {            _managerTypeAssemblies = new List<string>();            _managerTypesCache = new Dictionary<string, Type>();            _managerInstancesCache = new Dictionary<string, IManagerBase>();            EnableManagerInstanceCache = true;            //if (Platform == CommunicationPlatform.Local)            //{            //    foreach (string file in ManagerAssembly)            //    {            //        if (File.Exists(String.Format("{0}.dll", file)))            //        {            //            Assembly assembly = Assembly.Load(file);            //                _managerTypeAssemblies.Add(assembly);            //        }            //    }            //}        }......

在上面的代碼中,CommunicationPlatform為Local的情況被注釋掉了,但是沒有直接刪除。被注釋的代碼的作用是添加程式集到_managerTypeAssemblies類型中。可能是的原因是,系統現在不再支援Local模式,而只支援.net Remoting模式,所以這段代碼會被注釋。

 

3  因為考慮不周全,導致代碼中注釋與功能並存。保留注釋是為了出錯的情況下,協助分析代碼

來看下面的二個公用方法的定義,一個是反射調用靜態方法,另一個是反射調用靜態屬性的值。

 /// <summary>/// 靜態方法的調用/// </summary>/// <param name="file"></param>/// <param name="typeName"></param>/// <param name="methodName"></param>/// <returns></returns>public static object InvokeStaticMethod(Type typeName,string methodName,object [] args)        {            //Assembly  assembly = Assembly.LoadFile(file);            //Type type = assembly.GetType(typeName);            Assembly assembly = typeName.Assembly;            //obj2 = Activator.CreateInstance(type, args);            System.Reflection.MethodInfo method = typeName.GetMethod(methodName,new Type[]{ typeof(object)});           // object obj= assembly.CreateInstance(typeName);           // object obj = Activator.CreateInstance(typeName, args);            return typeName.InvokeMember(methodName, BindingFlags.Public | BindingFlags.Static, null, null, args);        }        public static object GetStaticPropertyValue(Type type, string propertyName)        {            object objec=CreateObjectInstance(type);            PropertyInfo propertyInfo = type.GetProperty(propertyName,BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);            //type.GetProperty(propertyName).GetValue(null, null);            return propertyInfo.GetValue(objec, null);        }

 

從上面被注釋的代碼中可以看到,需要的代碼與被注釋的代碼共同存在。可能因為參數或是條件的不同,被注釋的代碼可以運行,是正確的,但是當前情況下,沒有被注釋的代碼才可以運行。公用架構的開發本身要考慮的條件很多,測試也要充分才能保證無錯。從這裡也可以看出,反射給代碼重構帶來障礙,因為不知道代碼在哪裡會被反射調用,所以代碼只有等到運行出錯之後才發現。

除非正常調用情況下無法實現,應該減少反射調用代碼。或者對反射調用代碼進行封裝,所有的反射調用放在一個ReflectionHelper類型中,如果要尋找問題,只需要在這個類型的相應方法中打斷點即可。

 

4  異常處理機制的改變,導致代碼中捕獲異常的代碼被注釋

請看下面的二個方法,用於拷貝檔案和拷貝目錄

//bakup file public static BackupFile(string sourceFileName, string destFileName){          try           {                System.IO.File.Copy(sourceFileName, destFileName, true);                return true;            }            catch (Exception e)            {                throw e;            }}public static void CopyDirectory(string oldDir, string newDir)        {            try            {                DirectoryInfo dInfo = new DirectoryInfo(oldDir);                CopyDirInfo(dInfo, oldDir, newDir);            }            catch (Exception exc)            {                throw new Exception(exc.ToString());            }        }

這種依靠返回true/false的得知代碼是否執行成功。我現在比較反感這樣的代碼。因為如果拷貝檔案或拷貝目錄出錯,沒有報錯,異常在這裡被捕獲。而且第二個方法CopyDirectory中,拋出異常後會改變異常的堆棧資訊,這樣導致比較難發現錯誤。如果是WinForms程式,應該以下面的方式處理異常

 CustomExceptionHandler eh = new CustomExceptionHandler();            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CustomExceptionHandler.CurrentDomain_UnhandledException);            Application.ThreadException += new ThreadExceptionEventHandler(eh.OnThreadException);       

在程式的入口處,設定UnhandledException 和ThreadException 的處理情況,程式中有發生異常後,流程會跳轉到這裡,作統一的處理。以我的實踐,像下面這樣的方法,不應該這樣處理

/// <summary>        /// 複製檔案,如果目標檔案已經存在則覆蓋掉        /// </summary>        /// <param name="oldFile">源檔案</param>        /// <param name="newFile">目標檔案</param>        public static void CopyFile(string oldFile, string newFile)        {            try            {                File.Copy(oldFile, newFile, true);            }            catch (Exception exc)            {                throw new Exception(exc.ToString());            }        }

而修改的異常捕獲策略之後,代碼像這樣,也不友好

/// <summary>        /// 複製檔案,如果目標檔案已經存在則覆蓋掉        /// </summary>        /// <param name="oldFile">源檔案</param>        /// <param name="newFile">目標檔案</param>        public static void CopyFile(string oldFile, string newFile)        {            //try            //{                File.Copy(oldFile, newFile, true);            //}           // catch (Exception exc)            //{            //    throw new Exception(exc.ToString());            //}        }

應該直接去掉這個方法封裝,直接在代碼中調用File.Copy。

 

5  .NET架構的發展,導致一些代碼變成多餘但又沒有刪掉,先將其注釋

動態構造SELECT語句的欄位列時,在構造完成後,通常會給它們加上逗號

SELECT  ITEM_NO ,ITEM_GROUP FROM GBITEM
 

 

通常我們會用ArrayList或是IList<string> 把ITEM_NO和ITEM_GROUP聚集在一起,再迴圈一次,給每個字元的末尾增加一個逗號,最後去掉多餘的逗號:

 public static string ArrayToList(string[] ids, string separativeSign)    {        int num = 0;        string str = string.Empty;        foreach (string str2 in ids)        {            num++;            string str3 = str;            str = str3 + separativeSign + str2 + separativeSign + ",";        }        if (num == 0)        {            return "";        }        return str.TrimEnd(new char[] { ',' });    }

MSDN中字串類型string的Join方法,可以達到這個目的,只需要調用Join方法即可。MSDN中有例子解釋如下

如果 separator 為“,”且 value 的元素為“apple”、“orange”、“grape”和“pear”,則 Join(separator, value) 返回“apple, orange, grape, pear”。 如果 separator 為 nullNothingnullptrnull 引用(在 Visual Basic 中為 Nothing),則改用Null 字元串 (Empty)。

 
 
6 運行環境的改變,注釋掉代碼以便於以後發現問題

請參考下面的方法例子

 /// <summary>        /// 擷取一個檔案的絕對路徑(適用於WEB應用程式)        /// </summary>        /// <param name="filePath">檔案路徑</param>        /// <returns>string</returns>        public static string GetRealFile(string filePath)        {            string strResult = "";            //strResult = ((file.IndexOf(@":\") > 0 || file.IndexOf(":/") > 0) ? file : System.Web.HttpContext.Current.Server.MapPath(System.Web.HttpContext.Current.Request.ApplicationPath + "/" + file));            strResult = ((filePath.IndexOf(":\\") > 0) ?                filePath :                System.Web.HttpContext.Current.Server.MapPath(filePath));            return strResult;        }

這個方法之前可能是用Web環境中,現在改成WinForms或是控制台項目中,導致被注釋的代碼會報錯,於是將它注釋。關於路徑的選擇,AppDomain的BaseDirectory或是Application.ExecutePath都是獨立於運行環境的(ASP.NET,Console,WinForms,Windows Services),應該優先考慮使用。

 

7  測試資料以注釋的方式,保留中代碼中,增加對代碼的解釋
 string host = System.Configuration.ConfigurationManager.AppSettings["EmailHost"]; MailMessage m = new MailMessage();m.Subject = subject;m.SubjectEncoding = Encoding.UTF8;m.From = new MailAddress(from);m.To.Add(to);m.Body = body;m.BodyEncoding = Encoding.UTF8;m.IsBodyHtml = true;SmtpClient client = new SmtpClient();client.Host = host; //"ASHKGEX4.asia.ad.flextronics.com";client.Credentials = new System.Net.NetworkCredential("asia\baoshhli", "");client.Port = 25;client.DeliveryMethod = SmtpDeliveryMethod.Network;client.UseDefaultCredentials = false;client.Send(m);
 

如上面代碼中的host=ASHKGEX4.asia.ad.flextronics.com,作者測試問題時是用這個host也沒有報錯,於是將這個資料保留在代碼中,以方便以後代碼維護人員測試問題。

 

8  對每一個資料項目都進行注釋,必要的注釋和不必要的注釋混雜在一起

例如下面的代碼

DataTable Dt = new DataTable();DataRow Dr;Dt.Columns.Add("name");//名稱Dt.Columns.Add("type");//類型:1為檔案夾,2為檔案Dt.Columns.Add("size");//檔案大小,如果是檔案夾則置空Dt.Columns.Add("content_type");//檔案MIME類型,如果是檔案夾則置空Dt.Columns.Add("createTime");//建立時間Dt.Columns.Add("lastWriteTime");//最後修改時間

Add方法後面的對欄位的解釋,有的是是多餘的。有的是必要的。

我以為,多餘的注釋是:名稱,建立時間 ,最後修改時間  這三列的值可以通過代碼或是它本身的名字得知。

type這一列的注釋,我以為這是很有必要的,這可以減少維護人員的工作量。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.