C#新手常犯的錯(cuò)誤匯總
本文所述為C#新手常犯的錯(cuò)誤,但是實(shí)際上很多有經(jīng)驗(yàn)的程序員也經(jīng)常犯這些錯(cuò)誤,對(duì)此特別整理了一下,供大家參考。具體如下:
1、遍歷List的錯(cuò)誤,比如如下代碼:
List<String> strList =newList<String> for(int i =0; i<strList.Count; i++) { strList.RemoveAt(i); }
這段代碼看上去是刪除了所有元素,實(shí)際上每次調(diào)用RemoveAt方法會(huì)導(dǎo)致List元素索引重排,最后導(dǎo)致元素沒(méi)有完全刪除。
可以改成:
List<String> strList =newList<String> for(int i =0; i<strList.Count; i++) { strList.RemoveAt(i); i-=1; }
這樣就可以完全刪除List中的元素。
2、關(guān)于C#常量的錯(cuò)誤
比如你寫(xiě)了一個(gè)類(lèi)庫(kù),在里面定義了如下常量:
public const String str="First Version";
并且在另一個(gè)程序里引用了這個(gè)類(lèi)庫(kù),如果你修改了這個(gè)類(lèi)庫(kù)中的常量,發(fā)布了一個(gè)新的版本,那么再運(yùn)行之前的程序,你會(huì)發(fā)現(xiàn)常量還是原來(lái)的常量,并沒(méi)有改變。這是因?yàn)镃#在編譯的時(shí)候,常量直接作為元數(shù)據(jù)嵌入,解決方法是重新編譯整個(gè)解決方案或者使用屬性而不是直接訪問(wèn)常量。
3、當(dāng)把值類(lèi)型裝箱后,如果拆箱只能拆成原來(lái)裝箱前的類(lèi)型,比如:
Int32 a=3; Object obj=new object(); //這里裝箱成功,不會(huì)失敗 obj=i; //拆箱一定會(huì)失敗 Int64 b=(Int64)obj;
可以像這樣操作:
Int64 b =(Int64)(Int32)obj;
就能完成轉(zhuǎn)型
4、重載==運(yùn)算符的錯(cuò)誤:
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的重載運(yùn)算法 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); } } }
這里的問(wèn)題在于MyFun中會(huì)把NULL傳遞進(jìn)==運(yùn)算符函數(shù),導(dǎo)致運(yùn)行的時(shí)候報(bào)錯(cuò),正確的做法是:
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#中調(diào)用結(jié)構(gòu)的屬性或者方法必須用new來(lái)聲明結(jié)構(gòu)變量,否則會(huì)出錯(cuò)。
6、如果使用了params使用多個(gè)參數(shù),必須判斷參數(shù)是否為空,否則程序會(huì)有隱藏的BUG。
7、靜態(tài)成員在創(chuàng)建第一個(gè)實(shí)例的時(shí)候就會(huì)初始化,而且只被初始化一次,不要亂用靜態(tài)成員。
8、如果使用ref Object類(lèi)型參數(shù)接受String類(lèi)型會(huì)出錯(cuò),這是因?yàn)镃#要求參數(shù)必須使用正確的類(lèi)型,不加ref是可以的,如果一定要使用ref Object接受String類(lèi)型參數(shù),可以先轉(zhuǎn)型成Object,再引用傳遞。
9、類(lèi)的構(gòu)造函數(shù)中永遠(yuǎn)不要調(diào)用虛方法,比如:
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類(lèi)的一個(gè)成員"; } public class Parent { protected Ref my; public Parent() { my = new Ref(); //構(gòu)造方法中調(diào)用了虛方法 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(); } //重寫(xiě)虛方法 public override string GetString() { return my2.Str; //使用了內(nèi)部成員 } } }
這里在執(zhí)行基類(lèi)的構(gòu)造函數(shù)的時(shí)候會(huì)執(zhí)行到派生類(lèi)的虛方法GetString(),在獲取my2.Str的時(shí)候拋出異常,因?yàn)榇藭r(shí)派生類(lèi)對(duì)象還沒(méi)有被構(gòu)造。
10、在C#和SQL Server通信時(shí)要注意NULL的含義,在SQL Server里面這個(gè)值代表1900-1-1。SQL Server的空值可以使用DBNull來(lái)表示。
暫時(shí)就是這么多了,注意到以上10點(diǎn)可以在編程的時(shí)候減少大量BUG。
補(bǔ)充:
1、Math 三角函數(shù) 其中的參數(shù)為 弧度值,而非角度值。
2、WinForm 中的由相對(duì)路徑引發(fā)的bug:具體可以參考WinForm相對(duì)路徑的陷阱。
3、使用 xml, json 等序列化后的數(shù)據(jù)格式傳遞數(shù)據(jù)時(shí),如果傳遞的數(shù)據(jù)為數(shù)值型類(lèi)型,解析時(shí),最好先將其轉(zhuǎn)為string 然后 tryParse 成相應(yīng)類(lèi)型。
至于原因:如上的第三點(diǎn)、是裝箱和拆箱的問(wèn)題。
相信本文所述對(duì)大家C#程序設(shè)計(jì)可以帶來(lái)很大的幫助。
相關(guān)文章
C#查詢(xún)SqlServer數(shù)據(jù)庫(kù)并返回單個(gè)值的方法
這篇文章主要介紹了C#查詢(xún)SqlServer數(shù)據(jù)庫(kù)并返回單個(gè)值的方法,涉及C#操作SQLServer數(shù)據(jù)庫(kù)查詢(xún)的相關(guān)技巧,需要的朋友可以參考下2015-06-06C#數(shù)組學(xué)習(xí)相關(guān)資料整理
最近開(kāi)始學(xué)習(xí)c#,并有幸接觸到了數(shù)組方便的操作,感覺(jué)確實(shí)不錯(cuò),這里簡(jiǎn)單的整理下c#相關(guān)的學(xué)習(xí)資料,方便大家學(xué)習(xí)2012-09-09Unity 按鈕事件封裝操作(EventTriggerListener)
這篇文章主要介紹了Unity 按鈕事件封裝操作(EventTriggerListener),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04C#實(shí)現(xiàn)批量Word轉(zhuǎn)換Html的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用C#批量Word轉(zhuǎn)換Html的功能,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下2022-12-12C#編程實(shí)現(xiàn)發(fā)送郵件的方法(可添加附件)
這篇文章主要介紹了C#編程實(shí)現(xiàn)發(fā)送郵件的方法,具備添加附件的功能,涉及C#文件傳輸及郵件發(fā)送的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11C#實(shí)現(xiàn)操作PPT動(dòng)畫(huà)窗格并插入音頻文件
這篇文章主要為大家詳細(xì)介紹了如何利用C#實(shí)現(xiàn)操作PPT動(dòng)畫(huà)窗格并插入音頻文件,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-10-10c# 使用Task實(shí)現(xiàn)非阻塞式的I/O操作
這篇文章主要介紹了c# 使用Task實(shí)現(xiàn)非阻塞式的I/O操作,幫助大家更好的理解和學(xué)習(xí)c# 編程語(yǔ)言,感興趣的朋友可以了解下2020-11-11