C#新手常犯的錯誤匯總
本文所述為C#新手常犯的錯誤,但是實際上很多有經(jīng)驗的程序員也經(jīng)常犯這些錯誤,對此特別整理了一下,供大家參考。具體如下:
1、遍歷List的錯誤,比如如下代碼:
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中的元素。
2、關于C#常量的錯誤
比如你寫了一個類庫,在里面定義了如下常量:
public const String str="First Version";
并且在另一個程序里引用了這個類庫,如果你修改了這個類庫中的常量,發(fā)布了一個新的版本,那么再運行之前的程序,你會發(fā)現(xiàn)常量還是原來的常量,并沒有改變。這是因為C#在編譯的時候,常量直接作為元數(shù)據(jù)嵌入,解決方法是重新編譯整個解決方案或者使用屬性而不是直接訪問常量。
3、當把值類型裝箱后,如果拆箱只能拆成原來裝箱前的類型,比如:
Int32 a=3; Object obj=new object(); //這里裝箱成功,不會失敗 obj=i; //拆箱一定會失敗 Int64 b=(Int64)obj;
可以像這樣操作:
Int64 b =(Int64)(Int32)obj;
就能完成轉型
4、重載==運算符的錯誤:
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傳遞進==運算符函數(shù),導致運行的時候報錯,正確的做法是:
public static bool operator ==(Test t1, Test t2) { if ((t2 as object) == null) { return (t1 as object) == null; } else { return t2.Equals(t1); } }
5、C#中調用結構的屬性或者方法必須用new來聲明結構變量,否則會出錯。
6、如果使用了params使用多個參數(shù),必須判斷參數(shù)是否為空,否則程序會有隱藏的BUG。
7、靜態(tài)成員在創(chuàng)建第一個實例的時候就會初始化,而且只被初始化一次,不要亂用靜態(tài)成員。
8、如果使用ref Object類型參數(shù)接受String類型會出錯,這是因為C#要求參數(shù)必須使用正確的類型,不加ref是可以的,如果一定要使用ref Object接受String類型參數(shù),可以先轉型成Object,再引用傳遞。
9、類的構造函數(shù)中永遠不要調用虛方法,比如:
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; //使用了內(nèi)部成員 } } public class Child : Parent { private Ref my2; public Child() : base() { my2 = new Ref(); } //重寫虛方法 public override string GetString() { return my2.Str; //使用了內(nèi)部成員 } } }
這里在執(zhí)行基類的構造函數(shù)的時候會執(zhí)行到派生類的虛方法GetString(),在獲取my2.Str的時候拋出異常,因為此時派生類對象還沒有被構造。
10、在C#和SQL Server通信時要注意NULL的含義,在SQL Server里面這個值代表1900-1-1。SQL Server的空值可以使用DBNull來表示。
暫時就是這么多了,注意到以上10點可以在編程的時候減少大量BUG。
補充:
1、Math 三角函數(shù) 其中的參數(shù)為 弧度值,而非角度值。
2、WinForm 中的由相對路徑引發(fā)的bug:具體可以參考WinForm相對路徑的陷阱。
3、使用 xml, json 等序列化后的數(shù)據(jù)格式傳遞數(shù)據(jù)時,如果傳遞的數(shù)據(jù)為數(shù)值型類型,解析時,最好先將其轉為string 然后 tryParse 成相應類型。
至于原因:如上的第三點、是裝箱和拆箱的問題。
相信本文所述對大家C#程序設計可以帶來很大的幫助。
相關文章
C#查詢SqlServer數(shù)據(jù)庫并返回單個值的方法
這篇文章主要介紹了C#查詢SqlServer數(shù)據(jù)庫并返回單個值的方法,涉及C#操作SQLServer數(shù)據(jù)庫查詢的相關技巧,需要的朋友可以參考下2015-06-06Unity 按鈕事件封裝操作(EventTriggerListener)
這篇文章主要介紹了Unity 按鈕事件封裝操作(EventTriggerListener),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04C#編程實現(xiàn)發(fā)送郵件的方法(可添加附件)
這篇文章主要介紹了C#編程實現(xiàn)發(fā)送郵件的方法,具備添加附件的功能,涉及C#文件傳輸及郵件發(fā)送的相關技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-11-11