C#語言基礎常見問題匯總

來源: 51cto  發布時間: 2009-10-23 10:52  閱讀: 3590 次  推薦: 2   [收藏]  

  概述

  1、什么是C#?

  C#是Microsoft公司設計的一種編程語言。它松散地基于C/C++,并且有很多方面和Java類似。

  Microsoft是這樣描述C#的:“C#是從C和C++派生來的一種簡單、現代、面向對象和類型安全的編程語言。C#(讀做‘Csharp’)主要是從C/C++編程語言家族移植過來的,C和C++的程序員會馬上熟悉它。C#試圖結合Visual Basic的快速開發能力和C++的強大靈活的能力。”

  2、如何開發C#應用程序?

  .NET SDK包括了C#命令行編譯器(csc.exe),下一個版本的Visual Studio (Visual Studio 7 or Visual Studio.NET)會包含對C#開發的完整支持。

  3、C#可以取代Java?

  C#非常像Java語言——這兩種語言的核心和C++相比都有相似的優缺點。例如,兩個語言都有垃圾回收,但是兩個語言都沒有模板(template)。Microsoft已經中止了Visual J++產品,因此很難不認為Microsoft在使用C#來替代Java。

  4、C#可以取代C++?

  顯然是不,但是我們又很難說C++是新的.NET平臺上編寫代碼的最佳選擇。為了使.NET的運行層能完全發揮作用,它要求編程語言遵循某些特定的規則——其中之一就是所有的語言類型必須遵守通用類型系統(Common Type System,CTS)。不幸的是,許多C++特性不能被CTS支持。例如,模板和類的多重繼承。

  Microsoft對這個問題的答案是給C++提供可管理的擴展(Managed Extensions,ME), 這可以使C++遵守CTS。通過添加新的關鍵字來標記C++類有CTS的屬性(例如.-gc表示垃圾回收)。但是在創建新的工程時很難講為什么ME C++會比C#更合適。就特征(feature)而言它們很相似,但與C++不同的是C#從一開始就以.NET為環境設計的。ME C++存在的理由好像是將C++代碼移植(port)為.NET環境下的代碼。

  因此,這個問題的答案,很可能是C++作為一個.NET環境之外的語言將依然保留它的重要性;而通過ME將現存的C++代碼移植為適合.NET環境;但是很可能C#將是C++開發者開發新的.NET應用程序的最好選擇。

  8、C#是面向對象的嗎?

  是的,C#像Java和C++一樣,是一個面向對象的語言。

  9、C#有自己的類庫嗎?

  不,就像所有的.NET語言(VB.Net,JScript .Net...)一樣,C#訪問.NET類庫,C#沒有自己的類庫。

  基本類型

  1、C#提供什么標準類型?

  C# 支持的基本類型和C++很相似,包括int, long, float, double, char, string, arrays, structs 和 classes。然而,不要假設太多,名字可能很形似,但是一些細節不相同。例如C#中的long是64位的,而C++的long取決于平臺,32位的平臺上是32位的,64位的平臺上是64位的。class和struct在C++中幾乎完全一樣,但在C#中并不是這樣的。

  2、是否所有的C#類型都派生于一個公共的基類?

  是,也不是,所有的對象都可以看作從Object (System.Object)派生而來。但是為了把像int,float這樣的值類型實例看作是從Object對象派生的,這個實例必須通過一個裝箱的操作(boxing)轉化為引用類型。理論上,開發者可以忽略這些底層的轉化,但是認識到這點對于系統性能影響很重要。

  3、是否可以這樣認為,可以將一個值類型的實例作為參數傳給以對象為參數的方法?

  是的,例如:

class CApplication 
{    
  public static void Main() 
  {    
    int x = 25;    
    string s = “fred”;    
    DisplayMe( x );    
    DisplayMe( s ); 
   }    
    static void DisplayMe( object o ) 
    {    
      System.Console.WriteLine( “You are {0}”, o ); 
    }
} 

  將顯示:

  You are 25    
  You are fred

  4、值類型和引用類型的最基本的區別是什么?

  C#將類型分為兩類,一類是值類型,另一類是引用類型。大部分固有的基本類型(如int, char)是值類型,structs 也是值類型。引用類型包括類、接口、數組和字符串。基本的概念非常簡單,那就是一個值類型的實例代表了實際的數據(存在棧中),而一個引用類型的實例代表指向數據的指針或者引用(存在堆中)。

  C++開發者最容易混淆的地方是:C#已經自己預定義了一些類型作為值類型,一些作為引用類型,而一個C++的開發者希望能夠自己控制。

  例如,在C++中,我們可以這樣做:

  int x1 = 3; // x1 是堆棧上的值    
  int *x2 = new int(3) // x2 是堆的一個值的引用

  但是在C#中沒有這樣的控制:

  int x1 = 3; // x1是堆棧上的值    
  int x2 = new int();    
  x2 = 3; // x2還是堆棧上的值!

  5、既然 int是值類型,而 class是引用類型,那么int是怎樣從Object派生的呢?

  是這樣的,當int用作int時候,這是一個值類型(在棧上),然而,當它用作是Object時,這是一個引用堆上的整數值的引用類型。換而言之,當你將int看作對象時,運行層將它自動轉化為對象引用,這個轉化過程稱作裝箱(boxing)。這個轉換包括將棧里的值拷貝到了堆里,并且新建了一個對象的實例來引用該值。拆箱操作(unboxing)是個反過程——將對象轉化為基于棧的值類型。

  int x = 3;    
  // 堆棧上新的int類型,值為3    
  object objx = x;    
  // 堆上新的int, 設定值為3,x=3仍然在堆棧上    
  int y = (int)objx;    
  //新的int類型的值3在堆棧上,x=3在堆棧上,objx=3在堆上

  6、C#使用引用替代指針,那么C#的引用和C++的引用一樣嗎?

  不完全,基本的思想是一樣的,但是一個重要的區別是C#的引用可以是null。因此你不能確認C#的引用一定會是一個有效的對象。如果試圖使用一個值為null的引用,一個NullReferenceException 異常將被拋出。

  例如,看一看以下的方法:

void displayStringLength( string s ) 
{    
  Console.WriteLine( “String is length {0}”, s.Length ); 
} 

如果這樣調用它,這種方法將產生一個NullReferenceException 異常:

string s = null;    
displayStringLength( s ); 

當然有些情況你認為產生這樣一個異常是完全可以接受的結果,
但是在這個例子里最好按下面的代碼改寫一下:

void displayStringLength( string s ) 
{    
  if( s == null )    
  Console.WriteLine(“String is null”);    
  else    
  Console.WriteLine(“String is length {0}”, s.Length );    
} 

  class和struct

  1、struct在C++中是多余的,為什么C#還要使用它們呢?

  在C++中,一個結構和一個類幾乎就是一個同樣的東西。唯一的區別是缺省的成員的訪問級別不一樣(struct的缺省級別是public,class的缺省級別是private)。然而,在C#中struct和class完全不一樣。在C#中,struct 是值類型,而class是引用類型。另外struct不能從其他struct或者class繼承,盡管struct可以實現接口。struct沒有析構器。

  2、C#支持多重繼承嗎?

  C#支持接口的多重繼承,但是不支持類的多重繼承。

  3、C#接口和C++抽象類一樣嗎?

  不,不完全。C++的抽象類不能被實例化。但是它可以(而且經常是)包含執行代碼和數據成員。一個C#接口不能包含任何執行代碼或數據成員,它只是一組方法名稱和簽名(signature)。一個C#的接口更像是一個COM接口而不是抽象類。

  另一個主要的不同點是:C#類只能從一個類(不管是否抽象)繼承,但可以實現多重接口。

  4、C#構造器和C++ 構造器是否相同?

  非常相似,但是它們絕對不同。第一,C#析構器不保證在某個特定的時間被調用。實際上它根本不保證被調用。真實的情況是,C#析構器只是一個偽裝了的Finalize方法。具體點講,它是一個插入調用基類Finalize方法的Finalize方法。因此,這段代碼:

class CTest 
{   
  ~CTest()
   {    
  System.Console.WriteLine(“Bye bye” );    
  }    
}
實際上就是:
class CTest 
{    
  protected override void Finalize() 
  {    
    System.Console.WriteLine(“Bye bye” );    
    base.Finalize();    
  }   
} 

  如果你不相信,可以將一個 Finalize方法和一個析構器加入C#類中,然后就可以知道是如何編譯的了。

  5、什么是靜態構造器?

  它是整個類的一個構造器,而不是類的一個實例的構造器,它在類裝載的時候被調用。

  6、C#中所有的方法都是虛方法嗎?

  不,像C++一樣,缺省的時候,方法不是虛擬的,但都可以改為虛擬的。

  7、怎樣在C#中聲明一個純虛函數?

  在方法前使用abstract修飾符,類也可以標記為abstract(這是自然的)。注意,abstract方法不能有執行代碼(不同于C++中純虛方法)。

  和C++處理的不同

  1. 我“new”了一個對象,但是我怎樣刪除它?

  你不能,不允許你顯式地調用析構器,也沒有delete操作符。但是不必擔心,垃圾回收(garbage collection)會釋放你的對象,最終會的(也許會的)。

  2. 我試圖在棧上建立一個對象,但是C#編譯器不通過,這是怎么回事?

和C++不同,你不能在棧上建立一個對象的實例。類的實例總是被建立在堆上并且接受垃圾回收器(garbage collection)的管理。

  3. 我定義了一個析構器,但是它從來不能被調用,為什么?

  一個C#析構器實際上是Finalize方法的實現,但是運行環境不保證調用Finalize方法。你可以考慮通過調用GC.RequestFinalizeOnShutdown()方法試一下。

  4. 大多數的C#基本類型和C++的基本類型有相同的名字,它們一樣嗎?

不,C#中char和C++中的wchar是相同的。C#中所有的字符包括字符串都是Unicode的,C#中整型值是固定大小的,而在C++中其大小取決于處理器。例如,一個C#的int是32位的,而C++ 中int在32-bit處理器上是32位的,在64-bit處理器上是64位的,一個C#的long是64位的。

2
0
 
標簽:ASP.NET C#
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()