您现在的位置是:首页 >

不怕犯错误只要能改 C#几个经常犯错误汇总

火烧 2022-09-04 18:34:11 1053
C#几个经常犯错误汇总 在我们平常编程中 时间久了有时候会形成一种习惯性的思维方式 形成固有的编程风格 但是有些地方是需要斟酌的 即使是一个很小的错误也可能会导致昂贵的代价 要学会善于总结 从错误中汲

C#几个经常犯错误汇总  

    在我们平常编程中 时间久了有时候会形成一种习惯性的思维方式 形成固有的编程风格 但是有些地方是需要斟酌的 即使是一个很小的错误也可能会导致昂贵的代价 要学会善于总结 从错误中汲取教训 尽量不再犯同样错误 注重编程之美 代码的优雅 总结几个平常经常犯的错误     在C#编程中 字符型类型是最容易处理出错的地方 代价是非常昂贵 在 Net Framwork中 字符串是一个相当特别的引用类型 string本省就是一个不可继承的密封类 但是它具有了值类型所应用的特点 但是它在CLR中内存还是保存于托管堆之上 也就是说 当我们每次定义一个字符串类型的时候 就在堆内存中开辟一端内存 而当我们字符串被修改之后 它会创建一个新的内存 注意这里的内存是不连续的 而是通过修改栈内地址引用而拼凑字符串 不会改变源字符串在内存中的地址 所以有些程序员总是喜欢使用这样的方法格式化字符串     string  SelectText= select * from +TableName+ where UserName= +Name+ ;     上述代码 使用了字符串拼凑的方法 因为使用了多重串联 因此会在内存中创建两个不必要的字符串垃圾副本     其实在C#中 已经为我们提供了StringBuilder和String Fromat来解决此问题 虽然他们可以实现同样的功能 但是他们有质的变化 StringBuilder在内存中开辟的是一段连续内存 当增加新字符串时候 它会在栈中指向的同一个堆内存中连续存放字符 这就形成了性能的提升 所以我们将上面代码改成     string SelectText=string Format( select  *  from { } where UserName={ } TableName Name)     大多数开发人员都不知道内置的验证数据类型的方法 如System Int 因此很多人都是自己实现的 其实这是不妥的 因为这些基本类型中都存在自己固有的类型验证方法 下面这个就是自己实现验证的一个字符串是否是数值的代码

  

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

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

  

int output= ;  bool IsNumeric=int TryParse(value out output); 

  int TryParse是更快 更简洁的方法

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

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

  

public void  DALOneMethod()  {      SqlConnection  connection=null;      try      {            connection =new SqlConnection( );            connection Open();            //sqlmand 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       }  } 

不怕犯错误只要能改 C#几个经常犯错误汇总

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

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

  

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公共变量 它变成了只读 不能由调用者类进行修改

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

  

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

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

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

  

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

lishixinzhi/Article/program/ASP/201311/21846  
永远跟党走
  • 如果你觉得本站很棒,可以通过扫码支付打赏哦!

    • 微信收款码
    • 支付宝收款码