在我们平常编程中,时间久了有时候会形成一种习惯性的思维方式,形成固有的编程风格,但是有些地方是需要斟酌的,即使是一个很小的错误也可能会导致昂贵的代价,要学会善于总结,从错误中汲取教训,尽量不再犯同样错误,注重编程之美,代码的优雅,总结几个平常经常犯的错误。

1、在C#编程中,字符型类型是最容易处理出错的地方,代价是非常昂贵,在.Net Framwork中,字符串是一个相当特别的引用类型,string本省就是一个不可继承的密封类,但是它具有了值类型所应用的特点,但是它在CLR中内存还是保存于托管堆之上,也就是说,当我们每次定义一个字符串类型的时候,就在堆内存中开辟一端内存,而当我们字符串被修改之后,它会创建一个新的内存,注意这里的内存是不连续的,而是通过修改栈内地址引用而拼凑字符串,不会改变源字符串在内存中的地址,所以有些程序员总是喜欢使用这样的方法格式化字符串:

string  SelectText="select * from "+TableName+" where UserName='"+Name+"'";

上述代码,使用了字符串拼凑的方法,因为使用了多重串联,因此会在内存中创建两个不必要的字符串垃圾副本。

其实在C#中,已经为我们提供了StringBuilder和String.Fromat来解决此问题,虽然他们可以实现同样的功能,但是他们有质的变化,StringBuilder在内存中开辟的是一段连续内存,当增加新字符串时候,它会在栈中指向的同一个堆内存中连续存放字符,这就形成了性能的提升。所以我们将上面代码改成:

string SelectText=string.Format("select  *  from {0} where UserName={1}",TableName,Name);

2、大多数开发人员都不知道内置的验证数据类型的方法,如System.Int32,因此很多人都是自己实现的,其实这是不妥的,因为这些基本类型中都存在自己固有的类型验证方法,下面这个就是自己实现验证的一个字符串是否是数值的代码:

public bool CheckIfNumeric(string value){bool IsNumeric=true;try     {int i=Convert.ToInt32(value);     }catch(FormatException excepiton)     {           IsNumeric=false;     }return IsNumeric;}

虽然使用了try catch语句,这不是最佳的做法,更好的方法是下面使用Int.TryParse;

int output=0;bool IsNumeric=int.TryParse(value,out output);

int.TryParse是更快、更简洁的方法。

3、自己利用IDisposable接口手动释放内存

在.NET Framework中,对象的处理和使用一样重要,理想的方法是在使用完对象的时候,在类中实现IDisposable接口中的dispose方法进行内存的释放,当然在.Net本身提供的垃圾回收机制(GC)中就提供了这样的功能,在我们实例化类对象时,在类本身的析构函数中会调用dispose方法,GC在各级内存堆满的情况下,自动检查对象使用情况,去相应的释放内存,但是运行在非托管平台上的方法,需要我们自己手动释放内存,比如我们常见的SqlConnection对象,也就有了下面的创建、使用和处理方法:

public void  DALOneMethod(){    SqlConnection  connection=null;try     {          connection =new SqlConnection("。。。。。。。。。。。");          connection.Open();//sqlcommand。。run

     }catch(Exception exception)     {// manager exception     }finally     {            connection.Close();            connection.Disopse();     }}

上述代码是大部分程序员会出现的代码,乍看没啥问题,连接处理在最后一个代码中被明确调用,但是如果发生了一个异常,catch代码块就被执行,然后再执行最后一个代码块处理连接,因此在最后一个代码块执行之前,连接将一直留在内存中,大部分我们会在此处记录错误,一般涉及到IO操作,如果延时时间比较长的话,这个连接将在内存时间长时间停留。我们一个原则就是当对象不再使用的时候我们里面释放资源。

我们采用程序逻辑域来处理这个问题会更好:

public void  DALOneMethod(){using(SqlConnction  connection=new SqlConnection("。。。。。。。"))     {         connction.Open();// do SUAD     }}

当使用using代码快时,对象上的dispose()方法将在执行推出逻辑域的时候调用,这样就保证了SqlConnection的资源处理被尽早释放,当然这个方法也适用于实现IDisposable接口的类,当时个人不推荐这样做,在非常有把握的情况下可以手动释放,但是没把握还是叫给.net系统释放,因为本身类的析构函数就实现这个方法,当我们自己重写后,反而会导致系统误以为你自己定义了方法,而推迟释放资源,有兴趣可以研究下GC运行本质,假如能在第一代被释放的内存,如果我们重写dispose方法反而推迟到第二代内存堆中释放,显然是不可取的。

4、学会合理的管理公共变量,我们在系统中经常会滥用公共变量,没有做到合适的封装好。

static  void Main(string[]  args){            MyAccount  account=new MyAccount();//这地方不能随便的调用account里面的字段进行更改,但是缺改了        account.AccountNumber="ddddddddd";           Console.ReadKey();}public class MyAccount{public  string AccountNumber;public  MyAcctount()          {                AccountNumber="ssssssssssssss";          }}

在上面的MyAccount类中生命了一个AccountNumber公共变量,理想情况下,AccountNumber应该是只读的,不能让外界修改,但是这里MyAccount类却没有对它做任何控制。

声明公共做法应该是使用属性,如:

public  class  MyAccount{private stirng _accountNumber;public  string AccountNumber   {get {  return  _accountNumber;  }   }public  MyAccount()   {          _accountNumber="dddddddd";   }}

这里我们封装了AccountNumber公共变量,它变成了只读,不能由调用者类进行修改。

5、嵌套的异常处理,有的开发人员喜欢在方法末尾加上处理的嵌套方法,如

public class NestedExceptionHandling  {public void MainMethod()      {try          {//some implementation              ChildMethod1();          }catch (Exception exception)          {//Handle exception          }      }

private void ChildMethod1()      {try          {//some implementation              ChildMethod2();          }catch (Exception exception)          {//Handle exception           throw;

          }      }

private void ChildMethod2()      {try          {//some implementation          }catch (Exception exception)          {//Handle exception              throw;          }      }  }

如果相同的异常被处理多次,性能开销将会增加。

我们的解决方法是让异常处理方法独立开来,如:

public class NestedExceptionHandling  {public void MainMethod()      {try          {//some implementation              ChildMethod1();          }catch(Exception exception)          {//Handle exception          }      }

private void ChildMethod1()      {//some implementation          ChildMethod2();      }

private void ChildMethod2()      {//some implementation      }  }

6、大数据量上使用Dataset和DataReader混用,当单表数据量很大的情况,使用DataSet是一种很不明智的选择,应为DataSet是以DataTable内存形式存放数据量,一次性将数据拖入内存,当数据很大的情况下,这种方式是很吃内存的,相比DataSer,DataReader就显得优雅很多,它是每次读取一条数据,然后轮询调用机制,但是也有它的弊端,就是相对长连接,但是对内存消耗而言这是有利的,当然DataSet在大部分应用场景下也是有自己的优点,充分解耦、一次性操作、领域模型操作等方面,两者分情况分场景而用,这里只是稍微提提,根据场景分析区别。

转载于:https://www.cnblogs.com/zuoguanglin/archive/2012/03/20/2408915.html

C#几个经常犯错误汇总相关推荐

  1. 为什么打印还要另存为_锦学考研 | 打印准考证的常犯错误

    JINXUE EDUCATION 锦学2020考研 打印准考证的常犯错误,这些关键点要注意! 作为考场的通行证,准考证的重要性不言而喻,这些关键点你一定要注意,以往常犯的错误可不要再犯!1.时间:20 ...

  2. java代码书写易犯错误

    java代码书写易犯错误: 常见报错: 控制台报错: 找不到或无法加载主类 HelloWorld 原因: java.lang.NoClassDefFoundError: cn/itcast/day01 ...

  3. Oracle goldengate 11g错误汇总

    Oracle goldengate 11g错误汇总   1.ggsci执行错误 [oracle@doudou-NAS ~]$ ggsci ggsci: error while loading shar ...

  4. 【转】为什么自动车完全不可以犯错误

    为什么自动车完全不可以犯错误 有人跟我讲,我对Google的自动车要求太苛刻了.人无完人,所以Google的产品也不需要是完美的,只要"够好用"就有市场.世界上有那么多糟糕的司机, ...

  5. 遍历ArrayList易犯错误

    场景: 将ArrayList中符合条件的记录删掉,第一时间写出的程序如下: foreach (string aStr in  aList)             {                  ...

  6. 原型图和设计常犯错误,导致前端页面返工

    1.字体长度长了会出错 2.为空状态 3.成功提醒状态 4.列表过长分页 前端常犯错误 1.没加a链接的状态 转载于:https://www.cnblogs.com/Megasu/p/4213813. ...

  7. nagios监控配置错误汇总

    agios监控配置错误汇总 1.check_iftraffic监控网卡流量的配置及错误解决办法 服务端: 添加以下内容: vim /usr/local/nagios/etc/objects/comma ...

  8. oracle11g典型安装出错,oracle11g 安装错误汇总

    uname -a Linux oracle_master 2.6.32-220.el6.x86_64 #1 SMP Tue Dec 6 19:48:22 GMT 2011 x86_64 x86_64  ...

  9. 犯错误很正常,可怕的是同样的错误重复在犯!

    阅读本文大概需要 3.6 分钟. 我们不是圣人,无论是在生活中还是职场中,很难避免犯错误.如起床穿反衣服,公交车坐过站等.犯错误很正常,可怕的是同样的错误重复在犯. 生活中和工作中常见的错误类型大体有 ...

最新文章

  1. android系统的iphone,iPhone上安装Android系统详细步骤。
  2. 计算机基础知识第四章测试,计算机基础知识测试题第四章
  3. Django 3.1.5, CSRF verification failed. Request aborted.
  4. 一、Vmware安装Centos7虚拟机
  5. python读写文件实例_python读写文件的简单示例
  6. export function函数传参_从底层看前端(七)—— JavaScript到底有多少种函数?
  7. Linux命令整理 —— 目录结构
  8. 手把手搭建一个容器化+代理网关+可视化管理环境
  9. boot空间不足 linux,linux——boot空间不足
  10. thinkphp php 5.2,ThinkPHP5.2:时间查询(改进、优化)
  11. 深度学习数据驱动_模型驱动的物理层通信深度学习
  12. cmake 多次编译_Part01_CMakeLists构建管理多个模块的C代码
  13. 在ASP.NET中执行URL重写(一)
  14. adb interface 驱动问题(保证解决)
  15. 计算机公式里qf是什么,计算公式
  16. vue结合echarts开发柱状图+折线图合并的图表
  17. 【CSS3】模拟太阳系八大行星运行轨迹
  18. ES冷热分离架构设计:一招让你的ELK日志系统节省 50% 的硬盘成本
  19. python实战应用讲解-【numpy科学计算】scikits-statsmodels模块(附python示例代码)
  20. Cell Reports:任栓成/高东/胡志安/唐玲团队合作揭示压力性失眠发生的神经机制

热门文章

  1. 机器学习算法—集成算法原理详解
  2. elasticsearch api中的delete操作
  3. Intellij Idea 多模块Maven工程中模块之间无法相互引用问题
  4. 10个节省时间和改善工作流的Git技巧
  5. spark 应用程序性能优化:12 个优化方法
  6. Nginx-基础使用
  7. Android牟利之道(一)--界面嵌入有米广告
  8. 腾讯从百度挖来的AI Lab负责人张潼离职,要去阿里?...
  9. LeakCanary 源码分析
  10. 七种设计原则(二)单一职责原则