C#程序中注释过多的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),则改用空字符串 (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这一列的注释,我以为这是很有必要的,这可以减少维护人员的工作量。
C#程序中注释过多的8条理由的更多相关文章
- C#程序开发中经常遇到的10条实用的代码
1 读取操作系统和CLR的版本 OperatingSystem os = System.Environment.OSVersion; Console.WriteLine("Platform: ...
- 程序中条用其他程序中已经存在的PERFORM
PARAMETERS p_sub(40) TYPE c. DATA fssub(40) TYPE c. fssub = p_sub. TRY. PERFORM (fssub) IN PROGR ...
- (转)C#程序开发中经常遇到的10条实用的代码
原文地址:http://www.cnblogs.com/JamesLi2015/p/3147986.html 1 读取操作系统和CLR的版本 OperatingSystem os = System.E ...
- PL/0与Pascal-S编译器程序详细注释
学校编译课的作业之一,要求阅读两个较为简单的编译器的代码并做注释, 个人感觉是一次挺有意义的锻炼, 将自己的心得分享出来与一同在进步的同学们分享. 今后有时间再做进一步的更新和总结,其中可能有不少错误 ...
- 5 给我们的c#程序添加注释
注释是你的程序中的一个重要部分.在程序中添加注释是用来告诉你和其他人你的程序是做什么用的,你的思路是怎样的.注释可以用你熟悉的中文进行添加. 当你想暂时把你程序中的某些语句去掉的时候,不需要把他们删除 ...
- Native Application 开发详解(直接在程序中调用 ntdll.dll 中的 Native API,有内存小、速度快、安全、API丰富等8大优点)
文章目录: 1. 引子: 2. Native Application Demo 展示: 3. Native Application 简介: 4. Native Ap ...
- Android中使用ViewPager实现广告条
我们在使用电商或视频的手机客户端时,通常会看到广告条的效果.在网上搜索时才知道使用的是ViewPager,于是自己也做了一个Demo. 以下是效果图: 图中包括背景图片.文字描述以及白点. 其中Vie ...
- 程序中打印当前进程的调用堆栈(backtrace)
为了方便调式程序,产品中需要在程序崩溃或遇到问题时打印出当前的调用堆栈.由于是基于Linux的ARM嵌入式系统,没有足够的空间来存放coredump文件. 实现方法,首先用__builtin_fram ...
- Java异常(二) 《Effective Java》中关于异常处理的几条建议
概要 本章是从<Effective Java>摘录整理出来的关于异常处理的几条建议.内容包括:第1条: 只针对不正常的情况才使用异常第2条: 对于可恢复的条件使用被检查的异常,对于程序错误 ...
随机推荐
- mysql学习(2)-MySQL服务器优化
调优思路: 1.数据库设计与规划--以后再修该很麻烦,估计数据量,使用什么存储引擎 2.数据的应用--怎样取数据,sql语句的优化 3.mysql服务优化--内存的使用,磁盘的使用 4.操作系统的优化 ...
- Google搜索质量评估员指南
Google: 此文档是我们(谷歌)的一份搜索质量评估员指南,可作为搜索质量评估员的培训材料.其中主要介绍了一类名为“网址评分”的评分任务,此类任务要求评估员查看搜索查询与可能返回的相应结果.他们需要 ...
- tp 中关于大小写的问题
ThinkPHP3.2.3升级的若干问题和注意事项(持续更新) 现把ThinkPHP3.2.2在升级到3.2.3的过程中需要注意和可能的问题整理如下: (无论如何,在升级之前请确认备份) 1.首先3. ...
- python数据处理相关的一些知识点(学习点)
自己总结了一下就是存储,消息处理(异步,阻塞,队列,消息中间件) 参考岗位需求 数据爬虫工程师的岗位职责:1.分布式网络爬虫研发:不断完善现有抓取系统,通过对抓取.解析.调度.存储等模块的拆分与优化, ...
- maven 配置篇 之pom
maven 配置篇 之pom.xml(一) 博客分类: pm mavenXML配置管理项目管理junit 说完了settings.xml配置,下来说一下maven2的主要配置pom.xml ...
- Pair Project: Elevator Scheduler [电梯调度算法的实现和测试]
作业提交时间:10月9日上课前. Design and implement an Elevator Scheduler to aim for both correctness and performa ...
- load data ERROR 1197 (HY000)错误
有一份csv格式的文件,大小在14G左右.max_binlog_cache_size=4G. 登录mysql实例,选择对应的表通过load data往指定表里导数.大概20分钟左右,报以下错误: ER ...
- Excel VBA自动添加证书
---恢复内容开始--- 在说这个话题之前,我先解释一下为什么要加数字证书签名,它有什么作用,后面再解释如何添加.首先解释下证书添加的位置,如下图所示: 1.单击左上角的Office 按钮,选择右下角 ...
- 基于OWIN WebAPI 使用OAUTH2授权服务【授权码模式(Authorization Code)】
之前已经简单实现了OAUTH2的授权码模式(Authorization Code),但是基于JAVA的,今天花了点时间调试了OWIN的实现,基本就把基于OWIN的OAUHT2的四种模式实现完了.官方推 ...
- 互联网上那些excel文件
互联网上那些excel文件 文/玄魂 目录 互联网上那些excel文件 前言 1.1 查找包含指定值的excel文件 1.2 查找邮箱 1.3 查找身份证号 1.4 查找管理人员联系信息 1.5 获 ...