1. 程式人生 > >C#新手常犯的錯誤匯總

C#新手常犯的錯誤匯總

try 錯誤 獲取 math str 技巧 使用方法 fault cti

本文所述為C#新手常犯的錯誤,但是實際上很多有經驗的程序員也經常犯這些錯誤,對此特別整理了一下,供大家參考。具體如下:


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";

並且在另一個程序裏引用了這個類庫,如果你修改了這個類庫中的常量,發布了一個新的版本,那麽再運行之前的程序,你會發現常量還是原來的常量,並沒有改變。這是因為C#在編譯的時候,常量直接作為元數據嵌入,解決方法是重新編譯整個解決方案或者使用屬性而不是直接訪問常量。


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傳遞進==運算符函數,導致運行的時候報錯,正確的做法是:

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使用多個參數,必須判斷參數是否為空,否則程序會有隱藏的BUG。

7、靜態成員在創建第一個實例的時候就會初始化,而且只被初始化一次,不要亂用靜態成員。

8、如果使用ref Object類型參數接受String類型會出錯,這是因為C#要求參數必須使用正確的類型,不加ref是可以的,如果一定要使用ref Object接受String類型參數,可以先轉型成Object,再引用傳遞。

9、類的構造函數中永遠不要調用虛方法,比如:

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的時候拋出異常,因為此時派生類對象還沒有被構造。

10、在C#和SQL Server通信時要註意NULL的含義,在SQL Server裏面這個值代表1900-1-1。SQL Server的空值可以使用DBNull來表示。

暫時就是這麽多了,註意到以上10點可以在編程的時候減少大量BUG。


補充:

1、Math 三角函數 其中的參數為 弧度值,而非角度值。

2、WinForm 中的由相對路徑引發的bug:具體可以參考

3、使用 xml, json 等序列化後的數據格式傳遞數據時,如果傳遞的數據為數值型類型,解析時,最好先將其轉為string 然後 tryParse 成相應類型。

至於原因:如上的第三點、是裝箱和拆箱的問題。

相信本文所述對大家C#程序設計可以帶來很大的幫助。

除聲明外,跑步客文章均為原創,轉載請以鏈接形式標明本文地址
C#新手常犯的錯誤匯總

本文地址: http://www.paobuke.com/develop/c-develop/pbk23602.html






相關內容

技術分享C#中把任意類型的泛型集合轉換成SQLXML數據格式的實例技術分享C#簡單訪問SQLite數據庫的方法(安裝,連接,查詢等)技術分享C#.Net ArrayList的使用方法技術分享WinForm實現自定義右下角提示效果的方法
技術分享C#顯示文件夾下所有圖片文件的方法技術分享c#實現抓取高清美女妹紙圖片技術分享WinForm中的幾個實用技巧匯總技術分享C#中類與結構的區別實例分析

C#新手常犯的錯誤匯總