生活随笔
收集整理的這篇文章主要介紹了
The key of C# 学习笔记I-II
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
作者 :Kemin's booootLog? http://blog.csdn.net/keminlau/ Sunday, October 3, 2004
微軟提出的CLS(Common Language Specification, 通用語言標準)對能被用來編寫dotNET 程序的語言的最小功能集做出了規定。 就拿C#來說,它是目前程序設計語言“以效率換安全 ”發展潮流的一個產物。 “編譯器”把整個程序一次性地全部轉換為將被計算機執行的機器代碼;機器碼形成一個“可執行文件”,這個文件可以直接在計算機上運行。但因為機器碼是與某特定計算機相關聯,所以可執行文件只能在特定的類型的計算機上執行。 傳統過程化程序設計語言(如C),數據將由過程(或者叫“函數”“子例程”)代碼進行處理 ;在面向對象程序設計語言里,程序員創建各種“類”,并由此衍生出“對象”,一個對象就是代碼和數據的混合體,數據由對象自身進行處理 。這種觀念大大提高了代碼的“復用性”。 20世紀90年代,SUN公司推出了Java ,這種面向對象程序設計語言以C為藍本,但與C++ 有著顯著的區別 。JAVA摒棄了C++某些難看又難用的語法,也剔除了某些有危險性的C語言功能,但它保留了C語言簡潔緊湊的特點。 一個“操作符”( Operater)就是一個將使計算機執行某一個特定操作的符號或者單詞; 在C#及其他很多現代程序設計語言里,程序代碼 都必須寫成稱為“類”和“方法”的單元。 最簡單的C#程序 僅包含一個類,這個類又僅包含一個方法---》Main()入口函數。 一個方法聲明 將由一個修飾符(such as static),一個返回值類型(such as void),一個方法名稱,一個括在一對圓括號的輸入參數列表,一個包含著該方法代碼主體的語句塊等組成. 一個方法 就是一組用來完成某項特定任務的程序代碼. 一個表達式 可以是一個變量、一個常量或者是一個操作的執行或計算結果。 當C#對兩個整數做除法運算 時,它會把結果“截短”。幸好有求余(%)彌補。
Tuesday, October 5,2004
表達式(expression) 是由操作數(operand)和操作符(operater)構成。一個表達式有他的值,因此表達式可以作另一個表達式的操作數。 C家族 重要特征之一,精練,少打字。“復合賦值”操作符:+=加等;-+減等;++遞增;--遞減;…… C#編譯器的特殊功能 :出現在類、方法或者其他程序結構元素的前面且以三個斜線“///”開頭的注釋允許包含XML標記。C#編譯器將生成一個XML文件來存放這些標記。 在如今的數字計算機里,各種信息都將編碼為一系列“比特” ;比特是信息最簡單的表示形式。計算機硬件用電壓的高低或者有無來表示一比特; 現今的個人電腦大都是32位計算機,這是因為它們以32比特作為對數據進行存儲和處理的基本單位。早期的計算機每次只能處理8個比特,人們把8個比特稱為一個字節 。即使到了今天,字節仍是計算機領域最常用計量單位。 C#使用32比特(4個字節)來表示一個int類型的變量。一個int可以用來存儲正數和負數,所以int正式定義是“32比特的帶符號整數”。 二進制數是以2的冪次來表示的,2的N次冪就是一個二進制數字1后面跟上N個0所構成的一個二進制數。如:1-0000-0000等于256或28 現代的數字計算機里,負數通常被表示成“二進制補碼” 。二進制補碼指的是一種用來對正數和負數進行轉換的方法。如要表示-7(假設只有4個比特,頭一位為符號位):先得7的二進制表示:0111,再把0111按取反加一得“補碼”1001,1001即-7 C#關鍵字checked and unchecked激活溢出檢查機制 C#支持8種整型數據;選用整型數據的基本原則: @97%優先考慮使用int類型,32位便于處理也更有效率 @數值比int大,才選用long @如果需要使用磁盤文件來存儲或檢索大量小整數,考慮選用shot,byte 節約空間 字段和方法的相似之處是它們都是某個類或者某個結構的成員,但字段要簡單得多。一個字段其實就是一個變量或者一個取值固定不變的常數。
?
Thursday, October 7, 2004
在一條涉及多種運算的復雜語句里,C#將根據操作符的優先級和運算規則依次對各有關操作的操作數進行必要的類型轉換 (小容量向大容量轉)。在賦值操作中,等號右邊的表達式將被隱含地轉換為等左邊的變量的類型。 方法重載(overload) 就是一個方法的多種不同版本。如Console.WriteLine()方法的方法簽名(即輸入參數)可以是整數也可以是字符串。 同樣,操作符重載 是指用同一個操作符完成不同類型的操作的做法。如加號“+”用作數值加法和字符串合并。 C#里的“字符串里的引號 ”問題: 用轉義字符改變字符的正常含義如:string StringWithQuotes = "The name of the composition is/"Appalachian Spring./""; 用"@"關提掉轉義如: string Directory = @"C:/Program files/Key of c#"; 程序在內存中分布 (清楚存放部位) 代碼區:存放程序的代碼,程序的各個函數代碼塊; 全局數據區:存放程序的全局數據和靜態數據; 堆區:存放程序的動態數據; 棧區:存放程序的局部數據,可以說是函數中的數據; 特別的是棧區的數據,函數結束就會釋放. C#里的“引用” 不是C/C++里的“指針”,它是安全的“引用指針”,與C/C++“指針”完成類似的操作。引用類型數據(如類)的具體數據內容被保存在從堆 里分配的某個內存塊中,而這個內存塊的引用指針則保存在堆棧上。 從內存分配來理解null 和空串 的區別: 保留字null是一個取值為0的引用指針 ,這意味著C#不會多堆里分配內存。一個沒用引用任何堆內存的字符串變量叫作一個“null字符串”。 當某個字符串變量被賦值為null時,C#不會從堆里為它分配任何內存且堆棧上與它對應的值是0; 當某個字符串變量等于空字符串時,C#會從堆里為它分配一些內存,但字符串長度為0 。 文本是人與計算機進行交流的主要媒介。人們“強迫”計算機顯示文本輸出和接受文本輸入。即便是在只顯示數值的場合,計算機也必須把各有關的有關數值的二進制表示形式轉換為相應的文本輸出形式。 int與string互轉: ToString 是一個實例(instance)方法: string str = 123.ToString();//存在實例 Int32.Parse 是一個靜態(static)方法: int i = Int32.Parse("123");//創建實例 System名字空間還有一個很好用的Convert類 。程序員可以利用Convert類所提供的各種靜態方法對任意兩種數據類型進行類型轉換。如: int i = Convert.ToInt32(str); string str = Convert.ToString(i); C#兩種非整形數據類型:浮點數 和decimal 浮點數很常用,但有著一個先天的不足,就是精度不夠(float七位有效數字,double有15或16位) 對比于int和uint(32位),long和ulong(64位),decimal使用128位16個字節儲存數據;其中用96位表示有效數字(29個),5位表小數點位置(0-28),一位作符號位,共102位余26位。
Saturday, October 9, 2004
decimal舍入 “四舍五入”: Decimal.Truncate(Value);//向零方向舍入 Decimal.Floor(Value);//向負無窮方向舍入 “舍入為偶數”: Decimal.Round(Value,Digits);//Round(3.345,2) = 3.34 格式字符串 Consloe.WriteLine("{0,20:X5}{1,10:C2}",str1,str2);//{占位,輸出寬度:格式} 保留字“static”表明該方法為靜態方法 ,將作用于類或結構而不是作用于類或結構中的某個特定的方法,它必須與類或結構的名字配合使用,如Console.WriteLine(); 字段 就是在一個類的內部,但在這個類里的所有方法的外部所聲明的變量或者常數。如里字段只與這個類關聯而不與類的實例關聯,聲明為靜態static。 new保留字 的角色和作用: new表達式的返回值是一個引用(指針),它指系統從堆分配的那個內存塊。如:int[] aiArray = new int[] 進一步理解new的作用 :明確給對象在堆里分配空間 Random rand;//rand沒被初始化,什么都不做 rand = new Random();//為rand從堆分配內存和初始化操作等 C#不允許你用保留字const 去聲明一個數組——只有在編譯階段 被確定或計算出來的值才能被聲明為常數 ;數組需要一個new操作,而new操作只有等到運行階段 才會發生。 程序學一項基本原則 ——“把變量,不管是數組還是其它類型的變量,盡可能聲明為局部變量”;可是當需要在一個程序里頻繁調用某個方法而這個方法又要用到一個其元素都是些常數的數組時,就應該把那個數組搬到那個方法的外部并把它聲明為一個static字段。 .NET的Random類供程序員用來從從那顆隨機種子開始生成隨機數。
Monday, October 11, 2004
邏輯公式--德·莫干定律: !( A | B ) = !A & !B? !(?A & B?) = !A | !B C#中的char數據類型:代表單個字符 在C#里,可以用一個字符array去創建一個字符串,也可以把一個字符串轉換為一個字符array,但把一個C#字符串說成是一個字符array是不恰當的。C#有字符串數據類型string。 所有的程序設計語言都是用數值來代表字符的,但C語言把char看作是一種與int,short和long沒有什么不同的數值類型。在C里,char的寬度是8個比特且代表一個ASCII字符,但在C#里,char的寬度是16個比特且代表的是一個Unicode字符。C#里的char變量不是數值。 String.Chars 屬性 在 C# 中,該屬性為 String 類的索引器。獲取此實例中位于指定字符位置的字符。 new構造器的理解 如果要你創建一個由21個"@"字符構成的字符串,你會怎么做? string str = "@@@@@@@@@@@@@@@@@@@@@";//老實型 string str = new string('@' , 21);//簡單聰明
Wednesday, October 13, 2004
浮點數的比較運算 對浮點數進行比較,必須先舍入為相同精度再進行,因其的不精確性。 在需要測試某個float值或double值是否為無窮大或NaN時,不能直接用Single或Double結構中的PositiveInfinity、NegativeInfinity或NaN字段進行比較;應選用IsInfinity等方法來完成,因其有二義。 建議最好不要用“==”操作符去比較兩個布爾值 ,因為不小心少打一個等號,會致命的。可以使用異或操作符“^”將更穩妥。異或操作等價于“!=”操作符,所以有不少人把“^”稱為邏輯“不等于” 操作符。只要用“^”操作符對“!=”操作的結果再進行一次邏輯非處理,就能得到與“==”操作符同樣的效果,如: bWeAreCompatible = bYouLikeMahler == bILikeMahler bWeAreCompatible = !(bYouLikeMahler?^ bILikeMahler) 局部變量只在對它做出了聲明的那個{語句塊} 里才是可見的。這個語句塊有多大,求證中.... C#沒有“else語句”之類的東東,C#中的if語句由一個if部分和一個可選的else部分 構成。C#也沒有“else if語句”,是兩條if組合在一起而矣。 條件操作符 條件與 (&&)與條件或 (||) bExpression1 && bExpression2//如果bExpression1被求值為false,bExpression2將不會被求值 bExpression1 || bExpression2//如果bExpression1被求值為true,bExpression2將不會被求值 古怪“條件表達式 ”(?:),唯一三目操作符。 ??? 一、 C #的異常處理 所用到關鍵字
???? try 用于檢查發生的異常,并幫助發送任何可能的異常。
???? catch 以控制權更大的方式處理錯誤,可以有多個 catch 子句。
???? finally 無論是否引發了異常, finally 的代碼塊都將被執行。
???? throw 用于引發異常,可引發預定義異常和自定義異常。 ??? 二、 C #異常處理的格式
以下是引用片段: try { ??程序代碼塊; } catch(Exception?e) { ???異常處理代碼塊; } finally { ???無論是否發生異常,均要執行的代碼塊; }
有效的調試技巧 沒有漏網的魚 "This statement should never be executed."
for語句以保留字"for"開始,后面跟著一對圓括號,括號里有三個用分號隔開的表達式。注意,這是分號 在C#中惟一不被當作一個語句分隔符 來對待的地方!這三個表達式分別叫作for循環的“初始化表達式 ”、“循環條件表達式 ”和“步長表達式 ”。
?
Friday, October 15, 2004
算法“Sieve of Eratosthences”(Eratosthences之篩 )是一種用來生成素數 的算法。素數是只能被1和它本身整除的整數。2是第一個素數,也是素數中惟一的一個偶數。 CPU耗時 比較:方法調用 > 乘除運算 > 加減運算 switch語句 在Java中,switch語句只能處理整數。但C#中的switch語句不同,它還能夠處理字符變量。 switch (args[0]) { ??? case "老板": ??????? Console.WriteLine("早上好!我們隨時準備為您效勞!"); ??????? break; ??? case "雇員": ??????? Console.WriteLine("早上好!你可以開始工作了!"); ??????? break; ????default: ????????Console.WriteLine("早上好!祝你好運!"); ??????? break; }
與Java中的switch不同,C#的switch語句要求每一個case塊或者在塊的末尾提供一個break語句,或者用goto轉到switch內的其他case標簽。這就是所謂C#的“不允許留下swicth分支漏斗 ”的規定,不過你可以讓一個switch分支有多個switch標號 。如: .... case "*"://多種乘法運算符 case "x":// case "X":// ??? dResult = dNum1 * dNum2 ??? break; ....
編寫C#程序 的“基本工具”: 聲明語句; 賦值語句; 選擇語句(if, switch);//它們使程序能夠根據一個比較操作或者其他布爾操作的結果有選擇地改變執行路線 循環語句(while, do, for, foreach);//它們使程序能夠反復多次地執行同一組語句。 跳轉語句(return, break, continue, throw, goto);//它們使程序能夠從一個地方跳轉到另一個地方去繼續執行。 C#沒有>>>移位操作符 C#支持uint和ulong之類的無符號變量類型。因此,在C#中,右移操作符(即“>>”)對于無符號變量類型和帶符號變量類型(比如int和long)的處理方式不同。右移uint和ulong丟棄低位并把空出的高位設置為零;但對于int和long類型的變量,“>>”操作符丟棄低位,同時,只有當變量值是正數時,“>>”才把空出的高位設置成零;如果“>>”操作的是一個負數,空出的高位被設置成為1。 Java中不存在無符號的變量類型。因此,我們用“>>>”操作符在右移時引入負號位;否則,使用“>>”操作符。 枚舉器 枚舉器即enum類型(Enumerator,或稱為計數器),它是一個相關常量的集合。精確地說,enum類型聲明為一組相關的符號常量定義了一個類型名字。例如,你可以創建一個名為Fruit(水果)的枚舉器,把它作為一個變量值的類型使用,從而把變量可能的取值范圍限制為枚舉器中出現的值。 public class Demo { ??public enum Fruit { ??????? Apple, Banana, Cherry, Durian ??} ??public void Process(Fruit fruit) { ??? switch (fruit) { ??????? case Fruit.Apple: ??????????? ... ?????????? ?break; ??????? case Fruit.Banana: ??????????? ... ??????????? break; ????????case Fruit.Cherry: ????????????... ??????????? break; ??????? case Fruit.Durian: ??????????? ... ??????????? break; ????} ? } }
?
?
Sunday, October 17, 2004
C#方法調用 傳遞的參數 分四類: 默認的值參數(value parameter); //傳遞復制品 引用參數(reference parameter),關鍵字"ref ";//傳遞引用指針 輸出參數(output parameter),關鍵字"out "。//方法返回一個以上的返回值時使用 數組參數(array parameter),關鍵字"params " 引用參數 與輸出參數 的區別: “引用參數”與“輸出參數”非常相似。out 修飾符ref 修飾符有很相似的地方:傳址。事實上保留字“ref”和“out”本身在中間語言里的實現是一模一樣的。但C#中的ref參數與out參數還是有區別的: ref參數必須在進入方法之前得到賦值; out參數則必須在離開方法之前得到賦值。需要記住輸出參數 與通常的函數返回值 有一定的區別:函數返回值往往存在堆棧里,在返回時彈出;而輸出參數需要用戶預先制定存儲位置,也就是用戶需要提前聲明變量--當然也可以初始化。 using System; class Test????//拆分姓名 { static void ResoluteName(string fullname,out string firstname,out string lastname) { string[] strArray=fullname.Split(new char[]{' '}); firstname=strArray[0]; lastname=strArray[1]; } public static void Main() { ? ??????????????? //string MyName="Cornfield Lee"; ??????????????? Console.WriteLine("Enter Your Name:"); ??????????????? string MyName = Console.ReadLine(); string MyFirstName,MyLastName;
ResoluteName(MyName,out MyFirstName,out MyLastName);
Console.WriteLine("My first name: {0}, My last name: {1}", ??????????????? MyFirstName, MyLastName); } }
數組參數 (關鍵字"params ") using System; class Test??? //合計所有整數值 { static int Sum(params int[] args) { int s=0; foreach(int n in args) { s+=n; } return s; } static void Main() { int[] var=new int[]{1,2,3,4,5}; Console.WriteLine("The Sum:"+Sum(var));//傳數組變量 Console.WriteLine("The Sum:"+Sum(10,20,30,40,50));//傳能夠隱式轉化為數組的參數 } }
注意以下兩個規定: 數組參數只能是一維 的; 如果有多個輸入參數,就只允許一個輸入參數是params參數,而且它必須是參數表中的最后一個 。
Tuesday, October 19, 2004
數據的封裝 -對象 從本質上講,對象就是數據。隨著程序設計語言的發展,當人們開始把不同的數據組合在一起并當作一個整體 事物來對待時,“對象”出世 了!(拿日期對象作理解) 在聲明變量和常數時,你的程序其實就是在創建對象,數值常數和字符串都是對象。不過,有你的程序真正執行有關語句之前,對象是不會“出生的”。 日期對象:日期是由三個分立的數型變量組合而成的有機整體,這樣會大大簡化對日期數據的處理。 new操作符 將為新實例分配內存 并把它的的各個字段全部初始化 為0;堆內永遠是被初始化為的0的(就是堆棧可是值0或空指針null)。 Date[] aDate = new Date[5]; 如果Date是一個結構 :這條語句將從堆里為這個結構的5個實例(無需new初始化了,叫實例了嘛)分配內存并把各元素的所有字段全部初始化為0; 如果是一個類 ,這條語句將只為這個數組本身分配內存(上面也會為數組本身分本內存,不過還為結構實例分配)。這個數組的各個元素將是null。因為這個數組的各個元素都是一個引用(指針)。在使用這個數組的元素前,必須先用一個new構造實例(包括分配內存和初始化): aDate[3] = new Date(); C#數組是一個引用類型 ,數組中的各個元素將存儲在堆里。如 int[] ai?= new int[12];//使用new關鍵字在heap分配內存 除了數組,C#還有以下引用類型: ? 堆棧的執行效率要比堆的執行效率高,可是堆棧的資源有限,不適合處理大的邏輯復雜的對象 。所以結構 處理作為基類型對待的小對象 ,而類 處理某個商業邏輯 雖然結構 的初始化也使用了new 操作符 ,可是結構對象依然分配在堆棧上 而不是堆上,如果不使用“新建”(new),那么在初始化所有字段之前,字段將保持未賦值狀態,且對象不可用 如何選擇結構還是類 討論了結構與類的相同之處和差別之后,下面討論如何選擇使用結構還是類: 堆棧的空間有限,對于大量的邏輯 的對象,創建類 要比創建結構好一些 結構 表示如點、矩形和顏色這樣的輕量對象 ,例如,如果聲明一個含有 1000 個點對象的數組,則將為引用每個對象分配附加的內存。在此情況下,結構的成本較低。 在表現抽象 和多級別 的對象層次 時,類 是最好的選擇 大多數情況下該類型只是一些數據 時,結構 時最佳的選擇 面向過程到面向對象三步走: 封裝對象簡化輸入參數列表: static int DayOfYear(int iYear, int iMonth, int iDay){....}//三個 整型輸入參數
static int DayOfYear(Date dDate){....}//Date就好像是一個 已預先定義好的簡單類型 。
封裝與對象有關的方法到類(或結構)內部中去,成為類(或結構)的行為,進一步共享代碼 : 區分類(或結構)方法和字段的靜態性和實例性,進一步簡化使用 對象的代碼 。 .NET Framewrok里的每一個類和每一個結構ToString 方法,自已定義的類和結構也不例外,因為C#里所有類和結構都繼承自同一個祖先——System.Object類。雖然結構不支持繼承,但是所有的結構都是直接或間接從System.ValueType類繼承而來的。 若一個實例方法的聲明中含有 virtual 修飾符,則稱該方法為虛擬方法 。若其中沒有 virtual 修飾符,則稱該方法為非虛擬方法。 非虛擬方法的實現是不會變 的:無論是在聲明它的類的實例上調用該方法還是在派生類的實例上調用,實現都是相同的。與此相反,一個虛擬方法的實現可以由派生類取代 。
關鍵字"virtual"和"override "是密切相關的:如果A類繼承B類,就可以在A類里用一個override(重寫) 方法覆蓋掉B類里的同名的virtual方法。
不使用"override" 關鍵字也能覆蓋一個方法,但這種做法只有新、老方法的簽名和訪問性完全一致的情況下才能達到目的
?
Wednesday, October 20, 2004
類的字段初始化方法: 在聲明語句里直接初始化: class Date{ ??? public int iYear = 2004; ??? public int iMonth = 10; ??? public int iDay = 20; ??? ....... }
使用構造器: class Date{ ??? public int iYear, iMonth, iMonth;? ??? ??? public Date(){//無參數構造器 ??????? iYear = 1; ??????? iMonth = 1; ??????? iDay = 1; ??? } ??? ....... }
為了加快那些基于結構的數組 的創建速度 ,結構均不支持以上兩種初始化結構的方法。 C#的結構是一個關系重大的語言功能。和類一樣,結構也可以包含其他類型。由于結構在內部是值類型 的,所以結構有時也被稱為類的輕型版本 。同時,結構不承擔引用對象所帶來的開銷,除非在對其裝箱時例外。 C#的結構結論: 結構的定義是封閉 的(不能作為基類使用); 結構隱式地派生自System.ValueType ,而System.ValueType是所有值類型的超類型(終極基類)。 結構沒有默認的構造器 。 阻止創建 類實例的方法:一個私有的(private)空白無參數構造器,如:class clsA{...private clsA(){}...} 實際上如果我們能夠深刻地把握類的構造器的唯一目的 就是保證類內的成員變量能夠得到正確的初始化 ,我們對各種C#中形形色色的構造器便有會心的理解--它沒有理由不這樣! ? ⒈﹜ ┣━┒ ; `.┣─┒` ..wǒ 個ボ ┟━┃┍╄┓┟━│ ╃━ ? 人 ┝─┃┣╈┤┣━┃;/ ╈ ??? ┗━┘┗┸┛└━┛/┃┻ 相等性: 當你自行創建一個類或結構時,一定要對相等性 概念多做些思考。 要想成為一名合格的程序員,不僅要知道類對象和結構對象在相等性、賦值操作、方法調用等幾個方面有何不同,還要了解new操作符 對類對象和結構對象的處理有何不同。 要想創建出某個類 的一個實例,就必須使用一個new操作符,new操作符將進行幾項非常重要的處理: 從堆里為新對象分配內存; 有選擇地調用那個類的某一個構造器。 創建出某個結構的一個實例,也使用一個new操作符,new操作符將調用結構的惟一的無參數構造器(不能重寫),無參數構造器只是 把所有的字段初始化0或null而已,其他什么都不做 。不允許字段非零和上面結構創建速度有關的。 ?Reference Types versus Value Types
以下是引用片段: //?Reference?Type?(because?of?’class’) class??Ref?{?public?int?x,?y,?cx,?cy;?} //?Value?type?(because?of?’struct’) struct?Val?{?public?int?x,?y,?cx,?cy;?} static?void?SomeMethod?{ ???Ref?r1?=?new?Ref();??//?Allocated?in?heap ???Val?v1;??????????????//?Allocated?on?stack?(new?optional) ???r1.x?=?10;???????????//?Pointer?dereference ???v1.x?=?10;???????????//?Changed?on?stack ???RectRef?r2?=?r1;???? //?Copies?pointer?only ???RectVal?v2?=?v1;???? //?Allocate?on?stack?&?copies?members ???r1.x?=?20;???????????//?Changes?r1?and?r2 ???v1.x?=?20;???????????//?Changes?v1,?not?v2 }
?
Sunday, October 24, 2004
域的存取限制 集中體現了面向對象編程的封裝原則 。 只讀(readonly) 域不能進行寫操作,不變常量(const) 不能被修改,這兩者到底有什么區別呢? 只讀域只能在初始化--聲明初始化或構造器初始化--的過程中賦值,其他地方不能進行對只讀域的賦值操作,否則編譯器會報錯。只讀域可以是實例域也可以是靜態域。只讀域的類型可以是C#語言的任何類型。 但const修飾的常量必須在聲明的同時賦值,而且要求編譯器能夠在編譯時期計算出這個確定的值。const修飾的常量為靜態變量,不能夠為對象所獲取。const修飾的值的類型也有限制,它只能為下列類型之一(或能夠轉換為下列類型的):sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool, string, enum類型, 或引用類型。能夠聲明為const的引用類型只能為string或值為null的其他引用類型。 實際上,如果我們能夠理解const修飾的常量是在編譯時便被計算出確定的值,并代換到引用該常量的每一個地方 ,而readonly時在運行時才確定的量 --只是在初始化后我們不希望它的值再改變,我們便能理解C#設計者們的良苦用心,我們才能徹底把握const和readonly的行為! C#不提倡將域的保護級別設為public而使用戶在類外任意操作--那樣太不OO,或者具體點說太不安全!對所有有必要在類外可見的域,C#推薦采用屬性來表達。屬性不表示存儲位置 ,這是屬性和域的根本性的區別。 繼承 : 一個現有的類(基類)派生出一個新類(子類)時,子類將自動獲得所有被聲明在基類的非private方法、屬性和字段(注意基類的構造器是不會被繼承的。)。子類可以通過增加或者替換它繼承到的各種方法、屬性和字段的方式對基類的功能進行擴展 。 繼承能力是類和結構的重要區別之一。結構不支持繼承機制。 學海無涯,面向對象的程序設計既是一門科學,也是一門藝術 ,如果這本書能讓大家領略到它的一些奧妙 ,作者知足了!! 繼承與預構造器 (constructor initializer) 每一個構造器都會用一個預構造器 子類不能繼承基類的構造器但是可以“拿來用”,用關鍵字“base”指定父類和“this”指定本類中的構造器作為本構造器的預構造器。 在沒有指定時,父類的無參數構構造器為缺省的預構造器,即:“base()” 訪問限定符理解: 很多新手認為代碼共享就是最大限度的開放自己的代碼,總是不假思索把所有東西都聲明為“public”,其實類里面的public成員應該越少越好,因為可以降低調試難道 ,還遵循“盡量掩藏數據。使類成為一個代碼黑箱 ”的原則。
Monday, October 25, 2004
One of the more powerful concepts in object-oriented programming is polymorphism . The roots of this word, "poly-" and "-morph" mean, when put together, "many forms." polymorphism(破利摩飛神 ):“poly-”表示多之意,“-morph”,形態形狀 多態實例: using System ; public class DrawingBase{ ??? public virtual void Draw(){//基類虛方法 ??????? Console.WriteLine("I'm just a generic drawing object."); ????} } public class Line : DrawingBase{ ??? public override void Draw( ){//子類重寫虛方法1 ??????? Console.WriteLine("I'm a Line."); ??? } } public class Circle : DrawingBase{ ??? public override void Draw( ){//子類重寫虛方法2 ??????? Console.WriteLine("I'm a Circle."); ??? } } public class Square : DrawingBase{ ??? public override void Draw( ){//子類重寫虛方法3 ??????? Console.WriteLine("I'm a Square."); ??? } } public class DrawDemo{ ??? public static int Main(string[] args){ ??????? DrawingBase [] dObj = new DrawingBase [4];//創建基類類型數組 ??????? dObj[0] = new Line( );//賦值類型向上轉換 ??????? dObj[1] = new Circle( );//聲明(編譯時)為基類類型,實際類型(運行時)為子類類型 ??????? dObj[2] = new Square( ); ??????? dObj[3] = new DrawingBase( ); ??????? foreach (DrawingBase drawObj in dObj) ??????????? drawObj.Draw( );//運行時“后綁定”各個Draw版本 ??????? return 0; ??? } }
as 運算符 用于執行可兼容類型之間的轉換。as 運算符用在以下形式的表達式中:expression as type as 運算符類似于類型轉換,所不同的是,當轉換失敗時,as 運算符將產生空,而不是引發異常。 請注意,as 運算符只執行引用轉換和裝箱轉換。as 運算符無法執行其他轉換。 is 運算 符用于檢查對象的運行時類型是否與給定類型兼容。 GetType() 方法與操作符typeof() 和System.Type 類 Type t = instance.GetType();//一個實例方法,返回一個Type對象 Type t = typeof(class);//一個操作符,操作數為一種類型非某一實例,也是返回一個Type對象 相等性比較:bool b = instance.GetType() == typeof(class); 所謂“實現一個接口 ”指的是把該接口所聲?? 明的方法都在某個類里實現出來。 接口本質上是類需要如何響應的定義。接口描述類需要實現的方法、屬性和事件,以及每個成員需要接收和返回的參數類型,但將這些成員的特定實現留給實現類去完成。 派生類可以重寫(override)基類里的虛(virtual)方法和屬性, 也可“隱藏”(new關鍵字)基類里的非虛成員。 操作符重載:() Operators are defined for the built-in types, but that's not all. ? You can add operators to your own types , allowing them to be used much like the operators with the built-in C# types. Requirement:you create a Matrix type and then do a mathematical operation with them.
Solution:
implement an Add() , DotProduct() , and other methods to get the job done. Matrix result = mat1.Add(mat2);? // instance or Matrix result = Matrix.Add(mat1, mat2);? // static or event worse Matrix result = mat1.DotProduct(mat2).DotProduct(mat3); // and so on...
?much easier to have a + operator for the add operation and a * operator for the dot product operation. Matrix result = mat1 + mat2; or
Matrix result = mat1 * mat2; or even better
Matrix result = mat1 * mat2 * mat3 * mat4;
總結
以上是生活随笔 為你收集整理的The key of C# 学习笔记I-II 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。