程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#基礎知識 >> C#語言基本的普遍疑難匯總(1)

C#語言基本的普遍疑難匯總(1)

編輯:C#基礎知識

概述

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位的。 




  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved