雖然這篇post的標題是新手常犯的錯誤,實際上不少有經驗的程序員也常常犯這些錯誤,我整理了一下,就當是筆記。
一、遍歷List的錯誤,好比以下代碼:html
List<String> strList =newList<String> for(int i =0; i<strList.Count; i++) { strList.RemoveAt(i); }
這段代碼看上去是刪除了全部元素,實際上每次調用RemoveAt方法會致使List元素索引重排,最後致使元素沒有徹底刪除。
能夠改爲:程序員
List<String> strList =newList<String> for(int i =0; i<strList.Count; i++) { strList.RemoveAt(i); i-=1; }
這樣就能夠徹底刪除List中的元素。
二、關於C#常量的錯誤
好比你寫了一個類庫,在裏面定義了以下常量:算法
public const String str="First Version";
而且在另外一個程序裏引用了這個類庫,若是你修改了這個類庫中的常量,發佈了一個新的版本,那麼再運行以前的程序,你會發現常量仍是原來的常量,並無改變。這是由於C#在編譯的時候,常量直接做爲元數據嵌入,解決方法是從新編譯整個解決方案或者使用屬性而不是直接訪問常量。
三、當把值類型裝箱後,若是拆箱只能拆成原來裝箱前的類型,好比:編程
Int32 a=3; Object obj=new object(); //這裏裝箱成功,不會失敗 obj=i; //拆箱必定會失敗 Int64 b=(Int64)obj;
能夠像這樣操做:json
Int64 b =(Int64)(Int32)obj;
就能完成轉型
四、重載==運算符的錯誤:ide
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace UseOperator { class Program { static void Main(string[] args) { Test t1 = new Test(); t1.MyFun(); Console.ReadLine(); } } class Test { public void MyFun() { Test t = new Test(); if (t == null) { Console.WriteLine("t爲空!"); } else { Console.WriteLine("t不爲空!"); } } //存在BUG的重載運算法 public static bool operator ==(Test t1, Test t2) { return t2.Equals(t1); } public static bool operator !=(Test t1, Test t2) { return !(t1 == t2); } //覆蓋HashCode public override int GetHashCode() { return base.GetHashCode(); } public override bool Equals(object obj) { return base.Equals(obj); } } }
這裏的問題在於MyFun中會把NULL傳遞進==運算符函數,致使運行的時候報錯,正確的作法是:函數
public static bool operator ==(Test t1, Test t2) { if ((t2 as object) == null) { return (t1 as object) == null; } else { return t2.Equals(t1); } }
五、C#中調用結構的屬性或者方法必須用new來聲明結構變量,不然會出錯。
六、若是使用了params使用多個參數,必須判斷參數是否爲空,不然程序會有隱藏的BUG。
七、靜態成員在建立第一個實例的時候就會初始化,並且只被初始化一次,不要亂用靜態成員。
八、若是使用ref Object類型參數接受String類型會出錯,這是由於C#要求參數必須使用正確的類型,不加ref是能夠的,若是必定要使用ref Object接受String類型參數,能夠先轉型成Object,再引用傳遞。
九、類的構造函數中永遠不要調用虛方法,好比:post
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace FransferVirtualFunction { class Program { static void Main(string[] args) { try { Child ch = new Child(); } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.Read(); } } public class Ref { public string Str = "這是Ref類的一個成員"; } public class Parent { protected Ref my; public Parent() { my = new Ref(); //構造方法中調用了虛方法 Console.WriteLine(GetString()); } //虛方法 public virtual string GetString() { return my.Str; //使用了內部成員 } } public class Child : Parent { private Ref my2; public Child() : base() { my2 = new Ref(); } //重寫虛方法 public override string GetString() { return my2.Str; //使用了內部成員 } } }
這裏在執行基類的構造函數的時候會執行到派生類的虛方法GetString(),在獲取my2.Str的時候拋出異常,由於此時派生類對象尚未被構造。
十、在C#和SQL Server通訊時要注意NULL的含義,在SQL Server裏面這個值表明1900-1-1。SQL Server的空值可使用DBNull來表示。
暫時就是這麼多了,注意到以上10點能夠在編程的時候減小大量BUG。spa
原文出自:王銳 http://www.shunix.com unix
分割線
————————————————————————————————————————————————————————————
一、Math 三角函數 其中的參數爲 弧度值,而非角度值。
二、WinForm 中的由相對路徑引起的bug:WinForm中的暗殺殺手——相對路徑
三、使用 xml, json 等序列化後的數據格式傳遞數據時,若是傳遞的數據爲數值型類型,解析時,最好先將其轉爲string 而後 tryParse 成相應類型。
至於緣由:如上的第三點、是裝箱和拆箱的問題。