C#程式設計精華總結
C#學習總結
C#簡介:
1、C#是一種最新的、面向物件的程式語言
2、C#使得程式設計師可以在Microsoft開發的最新的.NET平臺上快速地編寫Windows應用程式
3、而且Microsoft .NET提供了一系列的工具和服務應用在應用程式的開發中
4、C#語言是是建立在Microsoft的.NET Framework之上,專門為與.NET Framework一起使用而設計的。
5、.NET Framework是一個功能非常豐富的平臺,可開發、部署和執行分散式應用程式。
6、C# 與.NET Framework的緊密結合使得程式開發更輕鬆、更高效。
C#與.NET的關係
1、C# 是一種程式語言,用於生成面向
2、.NET所支援的一些特性,C# 並不支援;而C# 支援的一些特性,.NET也可能不支援(如運算子過載)。
3、由於C# 是和.NET一起使用的,所以如果讀者想更高效地利用C# 開發應用程式,掌握.NET Framework的相關知識就非常重要。在許多情況下,C# 的特定語言功能取決於.NET的功能或依賴於.NET基類。
4、Microsoft Visual Studio.NET是MicroSoft公司為適應Internet高速發展的需要而隆重推出的新的開發平臺,是目前最流行的 Windows 平臺應用程式開發環境,可以用來建立 Windows 平臺下的
C#內建的輸入輸出方法
1、Console.WriteLine("Hello World"); 指定了它的行為。
WriteLine 是一個定義在 System 名稱空間中的 Console 類的一個方法。該語句會在螢幕上顯示訊息 "Hello, World!"
2、Console.ReadKey(); 是針對 VS.NET 使用者的。這使得程式會等待一個按鍵的動作,防止程式從 Visual Studio .NET 啟動時螢幕會快速執行並關閉。與C++的system("Pause");同效。
3、Console.Write()與Console.WriteLine()的區別是:前者輸出後不換行,後者輸出後自動換行
4、當 WriteLine() 函式有多個引數時,輸出第一個引數中的內容,而第二個引數中的內容替換掉第一個引數中對應位置的佔位符一起輸出。
Console.WriteLine("A:{0},a:{1}",65,97);
5、如果第一個引數沒有留佔位符,那麼第二個引數內容不輸出.
6、佔位符從零開始計數,且佔位符中的數字不能大於第二個引數的個數減一(要求佔位符必須有可替換的值).佔位符數字與第二個引數字元位置一一對應.
7、內建的 引用型別有:object、dynamic 和 string。
8、System 名稱空間中的 Console 類提供了一個函式 ReadLine(),用於接收來自使用者的輸入,並把它儲存到一個變數中。
例如: int num;
num = Convert.ToInt32(Console.ReadLine());
函式 Convert.ToInt32() 把使用者輸入的資料轉換為 int 資料型別,因為 Console.ReadLine() 只接受字串格式的資料
C# 中的建構函式
1、類的 建構函式是類的一個特殊的成員函式,當建立類的新物件時執行。建構函式的名稱與類的名稱完全相同,它沒有任何返回型別。
2、預設的建構函式沒有任何引數。但是如果你需要一個帶有引數的建構函式可以有引數,這種建構函式叫做引數化建構函式。這種技術可以幫助你在建立物件的同時給物件賦初始值,
3、一個類定義必須且至少有一個建構函式,如果定義類時,沒有宣告建構函式,系統會提供一個預設的建構函式,不帶任何引數的建構函式稱為預設建構函式。如果聲明瞭建構函式,系統將不再提供預設建構函式。
4、為了建立例項的方便,一個類可以有多個具有不同引數列表的建構函式,即建構函式可以過載。
5、建構函式的訪問屬性一般被定義為Public
6、建構函式好像不能被呼叫?
C# 中的析構函式
1、類的 解構函式是類的一個特殊的成員函式,當類的物件超出範圍時執行。解構函式的名稱是在類的名稱前加上一個波浪形(~)作為字首,它不返回值,也不帶任何引數。解構函式用於在結束程式(比如關閉檔案、釋放記憶體等)之前釋放資源。解構函式不能繼承或過載。
類的成員
區域性變數:在指定範圍內有效。
欄位:即類中的變數或常量,包括靜態欄位、 例項欄位、常量和只讀欄位。
方法成員:包括靜態方法和例項方法。
屬性:按屬性指定的get方法和Set方法對欄位進行讀寫。屬性本質上是方法。
事件:代表事件本身,同時聯絡事件和事件處理函式。
索引指示器:允許像使用陣列那樣訪問類中的資料成員。
關於C# internal的解釋
internal關鍵字是型別和型別成員的訪問修飾符。只有在同一個程式集的檔案中,內部型別或者是成員才可以訪問。這是msdn上對internal的描述。只有這麼一句話,但是具體怎麼理解呢?型別就是enum(列舉型別),class(類),interface(介面),struct(結構)等型別。型別成員如函式,成員變數等。那麼什麼是程式集呢?根據msdn上通俗易懂的解釋就是,一個完整的.exe或者是.dll檔案就是一個程式集。
C#中常用的類的修飾符
public:表示不限制對該類的訪問。
protected:表示只能對其所在類和所在類的子類進行訪問。
internal:不允許外部程式集使用該類。//這就是微軟自帶庫的類被定義為public的原因嗎,(一般我們不會把一個類定義為internal)
解釋:其實這個內部就是“同一程式集”的內部,也就是說,internal修飾的方法或者屬性,只要是在同一個程式集的中的其他類都可以訪問,如果二者不在同一名稱空間,只要使用using引用上相應的名稱空間即可,這裡,從另外一個方面也間接看出名稱空間並不是界定訪問級別的,而是保證全域性的類唯一性的。
private:只有.NET中的應用程式或庫才能訪問。//????把類定義為private有什麼用?
new:僅允許在巢狀類宣告時使用,表明類中隱藏了由基類中繼承而來的、與基類中同名的成員。
abstract:抽象類,不允許建立類的例項。
sealed:密封類,不允許被繼承。
自己的總結:
protected 只有自己的派生類可見。
internal只有自己包內的程式可見
protected internal 只有自己包內的派生類可見。
類成員訪問修飾符
Private:私有資料成員只能被類內部的函式使用和修改,私有函式成員只能被類內部的函式呼叫。派生類雖然繼承了基類私有成員,但不能直接訪問它們,只能通過基類的公有成員訪問。
Protected:保護資料成員只能被類內部和派生類的函式使用和修改,保護函式成員只能被類內部和派生類的函式呼叫。
Public:類的公用函式成員可以被類的外部程式所呼叫,類的公用資料成員可以被類的外部程式直接使用。公有函式實際是一個類和外部通訊的介面,外部函式通過呼叫公有函式,按照預先設定好的方法修改類的私有成員和保護成員。
Internal:內部成員只能在同一程式集中的檔案中才是可以訪問的,一般是同一個應用(Application)或庫(Library)。
預設訪問許可權問題:
1、訪問識別符號指定了對類及其成員的訪問規則。如果沒有指定,則使用預設的訪問識別符號。類的預設訪問識別符號是 internal,成員(包括屬性和方法)的預設訪問識別符號是 private。
C# 類的靜態成員
1、我們可以使用 static 關鍵字把類成員定義為靜態的。當我們宣告一個類成員為靜態時,意味著無論有多少個類的物件被建立,只會有一個該靜態成員的副本。
關鍵字 static 意味著類中只有一個該成員的例項。靜態變數用於定義常量,因為它們的值可以通過直接呼叫類而不需要建立類的例項來獲取。靜態變數可在成員函式或類的定義外部進行初始化。你也可以在類的定義內部初始化靜態變數。
2、靜態變數只能通過“類.靜態變數名”呼叫,類的例項不能呼叫; 非靜態變數當該變數所在的類被例項化後,可通過例項化的類名直接訪問。
3、靜態變數是全域性變數,被所有類的例項物件共享,即一個例項的改變了靜態變數的值,其他同類的例項讀到的就是變化後的值(非靜態變數是區域性變數,不共享的) ;
4、靜態成員不能訪問非靜態成員; 非靜態成員可以訪問靜態成員。
靜態和非靜態方法
方法分為靜態方法(方法宣告中含有static修飾符 )和非靜態方法(方法宣告中沒有static修飾符 )。
1.靜態方法
(1)靜態方法不對特定例項進行操作,在靜態方法中引用this會導致編譯錯誤。
(2)C#中通過關鍵字static來定義靜態成員。和例項成員不同,使用靜態成員時,圓點連線符的前面不再是某個具體的物件變數,而是類的名稱。如Console.WriteLine和Console.ReadLine等方法就屬於靜態方法,使用時沒有建立哪個具體的Console類的例項,而是直接使用類本身。
2.非靜態方法
非靜態方法是對類的某個給定的例項進行操作,而且可以用this來訪問該方法。
例如程式例7-4中的
CzMath c = new CzMath();
c.Swap(ref a, ref b);
而且在類的方法中通過this.number_name的方法引用某成員
就是先例項化CzMath的物件c,然後用物件c去呼叫非靜態方法Swap()。
輸出引數
1、在傳遞的引數前加out關鍵字,即可將該傳遞引數設定為一個輸出引數。
2、與引用引數類似,輸出引數也不開闢新的記憶體區域。它與引用型引數的差別在於,呼叫方法前無需對變數進行初始化。輸出型引數用於傳遞方法返回的資料。
3、out修飾符後應跟隨與形參的型別相同的型別宣告。在方法返回後,傳遞的變數被認為經過了初始化。
……
double ave;//ave未初始化
CzMath m = new CzMath();
m.Average(a, b, out ave);
……
class CzMath
{
public void Average(int x, int y, out double z)
{
z = Convert.ToDouble(x + y) / 2;
}
}
欄位概念及用途
欄位也叫成員變數,表示儲存位置,用來儲存類的各種資料資訊。
欄位又可分為靜態欄位、例項欄位、常量和只讀欄位。
例如:
private static int myvar;
private int myvar;
private const int myvar=5;
private readonly int myvar=6;
屬性的概念及用途
1、屬性定義了得到和修改相聯絡的欄位的方法。
2、C#中的屬性更充分地體現了物件的封裝性:不直接操作類的資料內容,而是通過訪問器進行訪問,藉助於get和set方法對屬性的值進行讀寫。
3、當讀取屬性時,執行get訪問器的程式碼塊;當向屬性分配一個新值時,執行set訪問器
例如,在Student類中可以通過Name屬性來封裝對私有欄位name的訪問:
public class Student
{
private string name;//欄位
public string Name //屬性//可定義多個屬性實現多個欄位的訪問器
{
get { return name; }
set { name = value; }
}
}
4、作為類的特殊函式成員,get和set訪問函式需要包含在屬性宣告的內部,而函式宣告只需要寫出get和set關鍵字即可。其中get訪問函式沒有引數,預設返回型別就是屬性的型別,表示屬性返回值;set訪問函式的預設返回型別為void,且隱含了一個與屬性型別相同的引數value,表示要傳遞給屬性的值。
5、通過屬性來訪問隱藏的欄位,例如:
Student s1 = new Student(“李明”);
Console.WriteLine(s1.Name);//呼叫get訪問函式訪問name欄位
Console.WriteLine(“請輸入新姓名:”);
s1.Name = Console.ReadLine();//呼叫set訪問函式修改name欄位
6、屬性可以只包含一個訪問函式,如只有get訪問函式,那麼屬性的值不能被修改;如只有set訪問函式,則表明屬性的值只能寫不能讀。
7、屬性的典型用法是一個共有屬性對應封裝一個私有或保護欄位,但這並非強制要求。屬性本質上是方法,在其程式碼中可以進行各種控制和計算。
8、注意:在C# 3.0中,提供了名為“自動屬性”特徵,它允許只寫出屬性及其訪問函式的名稱,編譯就會自動生成所要封裝的欄位以及訪問函式的執行程式碼。
例如,
public class Student
{
public string Name { get;set;}//比如該自動屬性封裝的欄位是那個怎麼確定?
}
其效果和下面傳統的定義方式是一樣的:
public class Student
{
private string name;//欄位
public string Name //屬性
{
get { return name; }
set { name = value; }
}
}
基類和派生類
1、為避免層次結構過於複雜,C#中的類不支援多繼承,即不允許一個派生類繼承多個基類,只有在類和介面之間可以實現多繼承。
2、.NET 類庫本身在構造過程中就充分利用了繼承技術。System.Object類是其他所有類的基類,不僅如此,C#是完全面向物件的程式語言,其中所有的資料型別都是從類中衍生而來,因此 System.Object類也是其他所有資料型別的基類。
3.訪問基類成員
訪問基類成員涉及隱藏基類成員和base關鍵字的使用。
(1)隱藏基類成員
大多數情況下,派生類不會一成不變地繼承基類中的所有成員,如可能希望在某些欄位中儲存不同的資訊、在某些方法中執行不同的操作等。這時就需要通過new關鍵字來隱藏基類中的成員。
(2) base關鍵字的使用
1.base關鍵字用來訪問當前物件的基類物件,進而呼叫基類物件的成員。
例如,可以StudentLeader類的PrintInfo方法改寫成:
public new void PrintInfo()
{
base.PrintInfo();
Console.WriteLine(Duty);
}
這樣,派生類StudentLeader的PrintInfo()方法就呼叫了其隱藏的基類方法。
2.base的另外一個用途是在派生類中呼叫基類建構函式,例如,上例中StudentLeader類的建構函式可以改寫為:
public StudentLeader(string a, string b, int c,string d):base(a, b, c)
{
Duty = d;
}
其中,base(a, b, c)表示呼叫基類構造
函式Student(a,b,c)。
虛擬方法和重寫方法
1.派生類很少一成不變地去繼承基類中的所有成員。
一種情況是派生類中的方法成員可以隱藏基類中同名的方法成員,這時通過關鍵字new對成員加以修飾;
另一種更為普遍和靈活的情況是將基類的方法成員定義為虛擬方法,而在派生類中對虛擬方法進行重寫。
後者的優勢在於它可以實現執行時的多型性,即程式可以在執行過程中確定應該呼叫哪一個方法成員。
2、基類的虛擬方法通過關鍵字virtual進行定義,而派生類的重寫方法則通過關鍵字override進行定義。
抽象類和抽象方法
1>基類中的虛擬方法允許在派生類中進行重寫,並在呼叫時動態地決定是執行基類的方法程式碼,還是執行哪一個派生類的方法程式碼。
2>C#中還可以為基類定義抽象方法,它強制性地要求所有派生類必須重寫該方法(看6>)。
3>抽象方法使用關鍵字abstract定義,並且不提供方法的執行體。
例如:
//抽象方法
public abstract void Area();
4>包含抽象方法的類必須是抽象類,它也需要使用關鍵字abstract加以定義。
例如:
public abstract class Shape
{
//類的成員定義...
}
5>對於抽象類,不允許建立類的例項。
6>抽象類之間也可以進行繼承。抽象類要求其所有派生類都繼承它的抽象方法;而如果派生類不是抽象類,它就必須重寫這些抽象方法並提供實現程式碼。
7>和虛擬方法類似,派生類中對抽象方法的重寫也通過override關鍵字進行。抽象方法不能是私有的,而且抽象方法及其重寫方法的訪問限制應當相同。最後,抽象方法不能同時使用virtual關鍵字進行修飾。
【例7-11】抽象類和抽象方法。
public abstract class Shape
{ //定義Shape抽象類
public const double PI = 3.14;
public abstract double area(); //抽象方法,不需要定義處理
}
密封類和密封方法
1、抽象類本身無法建立例項,而強制要求通過派生類實現功能。與之相反的是,在C#中還可以定義一種密封類,它不允許從中派生出其他的類。密封類通常位於類的繼承層次的最低層,或者是在其他一些不希望類被繼承的情況下使用。
密封類使用關鍵字sealed定義,例如:
public sealed class Circle : Shape
{
//類的成員定義...
}
2、說明
(1)有趣的是, 儘管密封類和抽象類是截然相反的兩個概念,但它們並不衝突:一個類可以同時被定義為密封類和抽象類,這意味著該類既不能被繼承、也不能被例項化。這隻出現在一種情況之下,那就是該類的所有成員均為靜態成員,Console類就是這樣的一個類。
(2)類似的,如果方法在定義中使用了關鍵字sealed,它就成為密封方法。與密封類的不同之處在於密封類是指不允許有派生類的類,而密封方法則是指不允許被重寫的方法。密封方法所在的類不一定是密封類(這一點與抽象方法不同),而如果該類存在派生類,那麼在派生類中就必須原封不動地繼承這個密封方法。此外, 密封方法本身也要求是一個重寫方法(即sealed和override必須在方法定義中同時出現)
c#中 foreach 用法
1、foreach迴圈用於列舉出集合中所有的元素,foreach語句中的表示式由關鍵字in隔開的兩個項組成。in右邊的項是集合名,in左邊的項是變數名,用來存放該集合中的每個元素。
2、該迴圈的執行過程如下:每一次迴圈時,從集合中取出一個新的元素值。放到只讀變數中去,如果括號中的整個表示式返回值為true,foreach塊中的語句就能夠執行。一旦集合中的元素都已經被訪問到,整個表示式的值為false,控制流程就轉入到foreach塊後面
的執行語句。
3、foreach語句經常與陣列一起使用
遍歷陣列:foreach(type objName in collection/Array)
注: objName的資料型別type必須與collection/Array物件的型別相同或比它大。
必須注意的是,藉助foreach,只能一一取得陣列中的元素,並不能利用這種語句改變陣列所儲存的元素。
c#中 as與is 用法
4、對於多維陣列foreach可一次性遍歷整個陣列,而for語句不行。
5、as運算子用於在兩個應用型別之間進行轉換,如果轉換失敗則返回null,並不丟擲異常,因此轉換是否成功可以通過結果是否為null進行判斷,並且只有在執行時才能判斷。
例子 Object obj=new Object();
ClassA a= obj as ClassA;
if(a!=null) //在if判斷a是否為null
{
...
}
6、is運算子用於檢查物件是否與給定型別相容,並不進行實際的轉換。如果判斷物件引用為null,則返回false。由於僅僅判斷是否相容,因此不會丟擲異常。使用範圍,只適用於引用型別轉換、裝箱轉換和拆箱轉換,而不支援值型別轉換。
例子 if(obj is ClassA)
{
ClassA a=(ClassA) obj;
...
}
7、在實際工作中儘量使用as運算子,而少使用()運算子的顯示轉換的理由:
1> 無論是as和is運算子,都比世界使用()運算子強制轉換更安全。
2> 不會丟擲異常,免除使用try···catch進行異常捕獲的必要和系統開銷,只需要判斷是否為null。
3> 使用as比使用is效能更好(C#4.0權威指南上這麼說),驗證結果如下:第一次執行時有as時間更短(沒有截圖),但是多執行幾次之後,結果如圖。
c#中 object用法
object 型別是 .NET Framework 中Object