第一篇:C#測試試題
一、選擇題(50題/2分)
1、C#的數(shù)據(jù)類型分為()
A、值類型
B、引用類型
C、接口類型
D、類類型
引用類型:數(shù)組類型
類類型
接口類型
2、下面C#中關(guān)于命名空間說法錯(cuò)誤的是(B)A、命名空間用于組織相關(guān)的類型 B、命名空間可以嵌套 C、在同一個(gè)引用程序章,不同的命名空間中不允許有相同名稱的類 D、use用于引用命名空間
3、關(guān)于下面程序,說法正確的是()
btye
a=3 , c=5;btye d=a+c;Console.WriteLine(“ d=”+d);A、編譯通過,結(jié)果為8 B、編譯通過,結(jié)果為35 C、編譯不通過“byte
a=3 , c=5;”,有錯(cuò)誤,不能這樣定義變量 D、編譯不通過“btye d=a+c”有錯(cuò)誤,d應(yīng)該為int類型
注:所有的小數(shù)默認(rèn)是double類型,所有的整數(shù)默認(rèn)是int類型
4、關(guān)于下面程序執(zhí)行并運(yùn)行的結(jié)果是()
int
x=3;int
y=5;int
res=x+(x++)+(++x)+y;Console.WriteLine(res);
A、16
B、19
C、15
D、17 ++在前,先自加,在運(yùn)算 ++在后,先運(yùn)算,后自加、已知程序如下
Int a=3, b=4,c=8;If(a+b>c)If(++a==b){ Console.WriteLine(++a); } else { Console.WriteLine(a++);} 程序編譯并運(yùn)行,結(jié)果為()
A、5
B、4
C
5、編譯錯(cuò)誤
D、編譯通過,沒有任何輸出
如果if中代碼塊只有一條語句,那么可以省略大括號(hào)。、已知程序如下: Int
i=1, sum=0;While(i<=100){ Sum+=i;i++;} Console.WriteLine(sum);結(jié)果是()
A、5000
C、0
D、1、5050 …100 6 B
7、請選擇正確的語句()
A、for(int i=0;intj=0;j!=10;i++;j++)B、for(int i=0;j=0;
j=i=10;i++;
j++)C、for(int i=0;j=0;j!=10;
i++;
j++)D、for(int
i=0;
intj=0;
j==i==10;
i++;
j++)
8、C# 獲取數(shù)組的長度使用()方法;
A、.lengh
B、.length()
C、Length
D、Length()
9、在C#中,定義方法的語法正確的是()A、public
int Sum(int
x, int y){ Return x+y;} B、public
bool Sum(int y){ Return x+y;} C、public
int Sum(bool y){ Return x+y;}
x, int x, int
D、public
int(int
x, int
y){ Return x+y;}
10、在C#中下面關(guān)于循環(huán),下面說法錯(cuò)誤的是()。
A.while循環(huán)和for循環(huán)都是是先判斷條件表達(dá)式是否成立,若是成立,則執(zhí)行循環(huán)體;否則結(jié)束循環(huán)。
B.do-while循環(huán)在Java和C#中只有大括號(hào)換行及條件表達(dá)式不同,語法和執(zhí)行順序基本一樣。
C.for循環(huán)有時(shí)候可以使用整型變量做循環(huán)計(jì)算器,通過表達(dá)式限定計(jì)算器變量值控制循環(huán)。
D.foreach()自動(dòng)遍歷給定集合的所有值。
11、C#中分割字符串的方法是()
A、Split
B、Length
C、Insert
D、Copy
12、在C#中,下面關(guān)于引用傳遞說法正確的是()。
A、引用傳遞不用加ref關(guān)鍵字 B、使用引用傳遞值不會(huì)發(fā)生改變 C、使用引用傳遞值會(huì)發(fā)生改變 D、引用類型和值傳遞結(jié)果一樣
13、在C#中下面關(guān)于break和continue語句的使用說法正確的是()。A.continue語句的作用是退出當(dāng)前的循環(huán)結(jié)構(gòu),而break語句是跳出本次循環(huán),開始執(zhí)行下一次循環(huán)。
B.break語句和continue語句在當(dāng)前循環(huán)結(jié)構(gòu)中跳轉(zhuǎn)的位置基本相同。
C.在嵌套循環(huán)中,當(dāng)break和continue出現(xiàn)在內(nèi)層循環(huán)時(shí),可能會(huì)影響外層循環(huán)的執(zhí)行。
D.上面說法全部錯(cuò)誤。
14、C#中的if 的條件是()類型的
A、bool類型
B、int類型
C、string類型
D、引用類型
15、下列說法正確的是();
A、在C#中++的用法和Java中的一樣 B、在C#中++在前,是先運(yùn)算在加1 C、在C#中++在后,是先加1再運(yùn)算 D、以上說法都是正確的
16、下列說法錯(cuò)誤的是()
A、C#中的數(shù)據(jù)類型可分為值類型和引用
B、C#中bool類型的默認(rèn)值是false C、C#中變量的命名可以使用數(shù)字開頭 D、C#中緊跟在switch結(jié)構(gòu)后面表達(dá)式的值或變量是字符類型和string類型
17、使用Substring()方法從字符串a(chǎn)dministrator中截取str字符串,那么方法的兩個(gè)參數(shù)應(yīng)該分別為()。
A.7 3
B.6 3
C.7 9
D.6 8
18、C#的源文件的后綴名是()
A、.Java
B、.cs
C、.txt
D、.mdf
19、C#中常量的聲明使用()
A、final
B、const
C、static
D、args 20、C#中對數(shù)組的初始化正確的是()
A、int [] array={2,3,6,9,4};B、int [] arrays=new int[3]{1,6,9};C、int [] arr=new int[ ]{1,6,9};D、int [] arrays=new [2] char{1,6,9}
21、下面是一個(gè)關(guān)于轉(zhuǎn)義字符使用的控制臺(tái)應(yīng)用程序:
static void Main(string[] args){ String str = “大家” + 'u0022' + “好” + ''';Console.WriteLine(str);Console.ReadLine();} 程序運(yùn)行后,其輸出結(jié)果應(yīng)該為()。
.A.大家好
.B.“大家好”.C.大家“好’.D.‘大家好’
22、下列用于折疊代碼的方法為()。.A./.B./* */.C.///
.D.#region #endregion
23、仔細(xì)查看下面的這段代碼: static void Main(string[] args){ int i= 0;int j = 0;while(i < 3){ i++;if(i > 2){ break;} ++j;} Console.WriteLine(i);Console.WriteLine(j);} 程序運(yùn)行后,其輸出結(jié)果應(yīng)該為()。
.A.3,3.B.2,3.C.3,2.D.2,2
24、while語句和do-while語句的主要區(qū)別是()。
.A.do-while的循環(huán)體至少無條件執(zhí)行一次
.B.do-while允許從外部跳到循環(huán)體內(nèi)
.C.while的循環(huán)體至少執(zhí)行一次
.D.while的循環(huán)控制條件比do-while的嚴(yán)格
25、下列有關(guān)break語句的描述中,正確的是()。.A.循環(huán)體內(nèi)的break語句用于結(jié)束本次循環(huán)
.B.循環(huán)體內(nèi)的break語句用于跳出循環(huán)
.C.在循環(huán)體內(nèi),break語句可以被執(zhí)行多次
.D.當(dāng)嵌套循環(huán)時(shí),break語句可以退出最外層循環(huán)
26、下列哪個(gè)不可用作轉(zhuǎn)義字符前綴()。
.A.Unicode字符
.B.十六進(jìn)制
.C.十進(jìn)制
.D.八進(jìn)制
27、已知x為字符變量,則下列賦值語句中,執(zhí)行結(jié)果與其他3個(gè)不同的是()。
.A.x=’a’;.B.x=’u0061’;.C.x=(char)97;.D.x=’x0097’;
28、已知int[][] arr=new int [3][]{new int[3]{5,6,2},new int[5]{6,9,7,8,3},new int[2]{3,2}};則arr[2][2]的值是()。
.A.9.B.1.C.6.D.越界
29、以下的數(shù)組聲明語句中,正確的是()。.A.int a[3];.B.int [3] a;
.C.int[][] a=new int[][];.D.int [] a={1,2,3};30、可以用來遍歷數(shù)組或集合中所有元素的循環(huán)是()。
.A.while.B.do…while.C.foreach.D.If
31、下列關(guān)于數(shù)組的初始化不正確的是()。
.A.int []a =new int[2].B.int []a =new int [2]{1,2}.C.int []a={1,3}.D.int[]a;a={1,2}
32、一個(gè)美國學(xué)者提出了一種用方框圖來代替?zhèn)鹘y(tǒng)的程序流程圖,該圖符合結(jié)構(gòu)化程序設(shè)計(jì)原則,通常也把這種圖稱為()。
.A.結(jié)構(gòu)圖
.B.?dāng)?shù)據(jù)流圖
.C.N-S圖
.D.PAD圖
33、以下算法的輸出結(jié)果為()。public static int Max(int x, int y){ if(x > y)return x;else return y;} static void Main(string[] args){ int i = 3, j = 6;int z = Max(i, j);
Console.WriteLine(“{0}”, z);}.A.3.B.6.C.程序出錯(cuò)
.D.9
34、關(guān)于算法不正確的是()。
.A.算法是指為解決某一個(gè)問題而采取的步驟和方法的描述
.B.算法必須有開始和結(jié)束,并且必須保證算法規(guī)定的每一個(gè)步驟最終都能夠被完成
.C.算法的每一個(gè)步驟都是嚴(yán)格規(guī)定好的,不能產(chǎn)生歧義
.D.算法可以有0個(gè)輸出
35、下面關(guān)于類和對象的說法中,不正確的是()。
.A.類是一種系統(tǒng)提供的數(shù)據(jù)類型
.B.對象是類的實(shí)例
.C.類和對象的關(guān)系是抽象和具體的關(guān)系
.D.任何對象只能屬于一個(gè)具體的類
36、某工程有甲乙丙三人合作完成,過程如下:甲乙兩人用6天時(shí)間完成工程的1/3,乙丙兩人用兩天完成剩余工程的1/4,甲乙丙三人用5天時(shí)間完成剩余工程。如果總收入為1800元,則乙應(yīng)該分得多少?()
.A.330元
.B.910元
.C.560元
.D.980元
37、計(jì)算1+2+3+4+5…+100,結(jié)果是()
.A.4900.B.5000.C.5050.D.5150
38、一個(gè)家庭有兩個(gè)小孩,其中有一個(gè)是女孩,問另一個(gè)也是女孩的概率(假定生男生女的概率一樣)().A.1/2.B.1/4.C.3/4.D.3/8
39、您在前一家公司的離職原因是什么?().A.避免把“離職原因”說得太詳細(xì)、太具體;
.B.不能摻雜主觀的負(fù)面感受,如“太幸苦”、“人際關(guān)系復(fù)雜”、“管理太混亂”、“公司不重視人才”、“公司排斥我們某某的員工”等;
.C.回答時(shí)不要躲閃、回避,如“想換換環(huán)境”、“個(gè)人原因”等;
.D.不能涉及自己負(fù)面的人格特征,如不誠實(shí)、懶惰、缺乏責(zé)任感、不隨和等;
40、下面哪個(gè)單詞的中文意義是'客戶,客戶機(jī)'().A.wizard.B.file attributes.C.Destination Folder.D.Client
41、下面哪個(gè)單詞的中文意義是'發(fā)布'().A.release.B.RIP
.C.file attributes.D.toggle break point
42、下面哪個(gè)單詞的中文意義是'圖形用戶界面'()
.A.DBMS
.B.graphics library.C.debug.D.GUI
43、已知程序如下:
Int a=3,b=4,c=8;If(a+b>c)If(++a==b){
Console.WriteLine(++a);
}else{
Console.WriteLine(a++);
} 程序編譯并運(yùn)行,結(jié)果為()
A、5
B、4 C、編譯錯(cuò)誤
D、編譯通過,沒有任何輸出
44、以下代碼可以正常編譯的是()(多選)A、int i=1;double d=1.0;if(d==i){ Console.WriteLine(“d=i”);}
B、int i=1;int j=2;if(i=1&&j=2){ Console.WriteLine(“i=
1、j=2”);}
C、boolean b1=false;boolean b2=true;if(b1==b2){ Console.WriteLine“b1==b2”);} D、int i=1;if(i){ Console.WriteLine(“1==1”);}
45、關(guān)于while和do-while循環(huán),下列說法錯(cuò)誤的是()A、兩種循環(huán)除了格式不通過,功能完全相同
B、與do-while語句不同的是,while語句的循環(huán)至少執(zhí)行一次
C、do-while語句首先計(jì)算終止條件,當(dāng)條件滿足時(shí),才去執(zhí)行循環(huán)體中的語句 D、以上都不對
46、已知下面程序: Int x=0;————; do { } While(x++ 在下劃線中插入哪個(gè)語句,則程序輸出24(B) A、int y=22;B、int y=23;C、int y=24;D、int y=25; 47、已知程序如下: int x=5;Console.WriteLine(++x);{ int x=7;Console.WriteLine(x);} 程序編譯并運(yùn)行的結(jié)果為()A、編譯通過,輸出5和7 B、編譯通過,輸出6和7 C、編譯通過,輸出7和8 D、編譯錯(cuò)誤,因?yàn)閤已經(jīng)在main()方法中定義過 48、下列程序輸出結(jié)果為()Int a=0;Outer;for(int i=0;i<2;i++){ for(int j=0;j<2;j++){ if(j>i){ Continue outer;} a++;} } Console.WriteLine(a);A、0 B、2 C、3 D、4 49、引用類型的數(shù)據(jù)類型字段的缺省值為()A、0.0 B、0 C、null D、false 50、你覺得你個(gè)性上最大的優(yōu)點(diǎn)是什么?()A、沉著冷靜、條理清楚 B、立場堅(jiān)定、頑強(qiáng)向上 C、樂于助人和關(guān)心他人、適應(yīng)能力和幽默感 D、樂觀和友愛 引用類型是類型安全的指針,它們的內(nèi)存是分配在堆(保存指針地址)上的。String、數(shù)組、類、接口和委托都是引用類型。 強(qiáng)制類型轉(zhuǎn)換與as類型轉(zhuǎn)換的區(qū)別:當(dāng)類型轉(zhuǎn)換非法時(shí),強(qiáng)制類型轉(zhuǎn)換將拋出一System.InvalidCastException異常,而as不會(huì)拋出異常,它返回一個(gè)null值。用using創(chuàng)建別名:using console = System.Console;訪問限定符: public 該成員可以被其他任何類訪問 protected 該成員只能被其派生類訪問 private 該成員只能被本類的其他成員訪問 internal 該成員只能在當(dāng)前編譯單元的其他成員訪問 帶參數(shù)列表和返回值的Main方法: class Test { public static int Main(string[] args) { foreach(string arg in args) { ...} } } 構(gòu)造函數(shù)(constructor)包括實(shí)例構(gòu)造函數(shù)和靜態(tài)構(gòu)造函數(shù)。構(gòu)造函數(shù)與類名相同,且不能有返回值。例: class TestClass { TestClass()//實(shí)例構(gòu)造函數(shù):可以訪問靜態(tài)成員和實(shí)例成員,用于初始化實(shí)例成員 { ...} static TestClass()//靜態(tài)構(gòu)造函數(shù):只能訪問靜態(tài)成員,用于初始化靜態(tài)成員 { ...} } 類的靜態(tài)成員屬于類所有,不必生成實(shí)例就可以訪問,它是在載入包含類的應(yīng)用程序時(shí)創(chuàng)建的,但靜態(tài)方法不能訪問類的實(shí)例變量和方法。通常,靜態(tài)變量是在定義時(shí)就賦初始值的。類的實(shí)例成員屬于類的實(shí)例所有,不創(chuàng)建實(shí)例對象就無法對其進(jìn)行訪問,實(shí)例成員可以訪問類的 靜態(tài)成員和其它實(shí)例成員。調(diào)用基類的析構(gòu)函數(shù): class A { public A() { ...} } class B { public B(): base()//調(diào)用基類的析構(gòu)函數(shù) { ...} } 常量:其值是在編譯時(shí)設(shè)定的,必須是數(shù)值文字。默認(rèn)狀態(tài)下常量是靜態(tài)的。例: class A { public const double pi = 3.1415;} 常量是編譯時(shí)就確定的值,只讀字段是在運(yùn)行才能確定的值。比如運(yùn)行時(shí)才能確定的屏幕分辨率。 只讀字段只能在類的析構(gòu)函數(shù)中賦值。靜態(tài)只讀字段: class A { public static readonly int ScreenWidth;//靜態(tài)只讀字段 static A() //靜態(tài)析構(gòu)函數(shù) { ScreenWidth = 1024;//在靜態(tài)析構(gòu)函數(shù)中初始化 } } 在類的繼承中,類的析構(gòu)函數(shù)是不會(huì)被繼承的。一個(gè)派生類只能從一個(gè)基類繼承,不能同時(shí)從多個(gè)基類繼承,但可以通過繼承多個(gè)接口來達(dá)到相同目的。實(shí)現(xiàn)多繼承的唯一方法就是使用接口。例: class MyFancyGrid: Control, ISerializable, IDataBound {...} 密封類是不能繼承的類,抽象類不能被定義為密封類,且密封類的私有成員不能用protected修飾,只能用private。例: sealed class A {...} 關(guān)鍵字ref和out用于指定用引用方式傳遞方法的參數(shù)。 它們的區(qū)別是:ref參數(shù)必須初始化,而out參數(shù)不需要初始化。所以在方法處理代碼依賴參數(shù)的初始化值時(shí)使用ref,不依賴初始化值時(shí)使用out。對out參數(shù)即使在傳遞前對其進(jìn)行了初始化,其值也不會(huì)傳遞到方法處理函數(shù)內(nèi)部。傳遞時(shí)系統(tǒng)會(huì)將其設(shè)為未初始化。所以在方法內(nèi)部必須對out參數(shù)進(jìn)行初始化。 方法重載時(shí),必須參數(shù)數(shù)目和參數(shù)類型其中之一不同,返回值不同不能作為重載。C#不支持方法的默認(rèn)值,只能通過方法重載來實(shí)現(xiàn)。例: class A { int Method(int a) { ...} void Method(int a, int b)//參數(shù)數(shù)目不同 { //返回值不同不能作為重載 ...} } params參數(shù)用于一個(gè)不定數(shù)目參數(shù)的方法,一般后面跟一個(gè)數(shù)組。例: class A { public void Method(params int[] i) { ...} } 方法的覆蓋:指派生類覆蓋基類的同名方法,有二種方法 1)第一種是在派生類要覆蓋的方法前面加new修飾,而基類不需要作任何改動(dòng)。這種方法的缺點(diǎn)是不能實(shí)現(xiàn)多態(tài)。例: class A { public void Method()//無需任何修飾 { ...} } class B: A //從基類繼承 { new public void Method()//覆蓋基類的同名方法 { ...} } class TestClass { A Instance = new B(); Instance.Method();//這時(shí)將調(diào)用類A的Method方法,而不是類B的Method方法 } 2)第二種是在派生類要覆蓋的方法前面加override修飾,而基類的同名方法前面加virtual修飾。這樣就能實(shí)現(xiàn)多態(tài),例: class A { virtual public void Method() //基類定義虛方法 { //虛擬方法不能定義為private,因?yàn)閜rivate成員對派生類是無法訪問的...} } class B: A //從基類繼承 { override public void Method() //派生類覆蓋基類的同名虛方法 { ...} } class TestClass { protected void Test() { A Instance = new B(); //定義一個(gè)實(shí)例,類型為基類,從派生類創(chuàng)建 //派生類總是能夠向上轉(zhuǎn)換為其基類 Instance.Method(); //將調(diào)用派生類B的Method方法,而不是基類的,這就是多態(tài) } } 說明:new修飾的方法覆蓋不能實(shí)現(xiàn)多態(tài)的原因,是因?yàn)槭褂胣ew時(shí)編譯器只會(huì)實(shí)現(xiàn)早期綁定(early binding)。即調(diào)用的方法在編譯時(shí)就決定了:編譯器看到Instance.Method()而Instance的類是A,就會(huì)調(diào)用類A的Method()方法。 override修飾的方法覆蓋可以實(shí)現(xiàn)多態(tài)的原因,是因?yàn)閷?shí)現(xiàn)了后期綁定(late binding)。使用override時(shí)強(qiáng)制編譯器在運(yùn)行時(shí)根據(jù)類的真正類型正確調(diào)用相應(yīng)的方法,而不是在編譯時(shí)。 而基類的同名方法必須加virtual修飾。 類的靜態(tài)方法可能通過 類名.靜態(tài)方法名 這種格式來調(diào)用,不能使用 實(shí)例名.靜態(tài)方法名 這種方法調(diào)用。 因?yàn)轭惖撵o態(tài)方法為類所有(是屬于類本身的),而非實(shí)例所有(不是屬于類的實(shí)例的)。類的靜態(tài)方法可以訪問類的任何靜態(tài)成員,但不能訪問類的實(shí)例成員。C#中類的變量稱為字段。類的public變量稱為類的公共字段。 類的屬性由一個(gè)protected(也可以是private)字段和getter和setter方法構(gòu)成: class Address { protected string zipCode;//protected字段,注意大小寫 public string ZipCode { get //getter方法 { return zipCode; } set //setter方法 { zipCode = value;//被傳遞的值自動(dòng)被在這個(gè)value變量中 } };} 只讀屬性是指省略setter方法的屬性,只讀屬性只能讀取,不能設(shè)置。 屬性也可以用限定符virtual,override和abstract修飾,功能同其他類的方法。 屬性有一個(gè)用處稱為懶惰的初始化(lazy initialization)。即在需要類成員時(shí)才對它們進(jìn)行初始化。如果類中包含了很少被引用的成員,而這些成員的初始化又會(huì)花費(fèi)大量的時(shí)候和系統(tǒng)資源的話,懶惰的初始化就很有用了。C#中數(shù)組對象共同的基類是System.Array。將數(shù)組聲明為類的一個(gè)成員時(shí),聲明數(shù)組與實(shí)例化數(shù)組必須分開,這是因?yàn)橹荒茉谶\(yùn)行時(shí)創(chuàng)建了類的實(shí)例對象之后,才能實(shí)例化數(shù)組元素值。聲明: int[] intArray;//一維數(shù)組 int[,] int3Array;//三維數(shù)組 初始化: intArray = new int[3] {1,2,3};int[,] int2Array = new int[2,3] {{1,2,3},{4,5,6}};//聲明時(shí)可以初始化 遍歷: 1)一維數(shù)組 for(int i = 0;i < intArray.Length;i++);//Array.Length返回?cái)?shù)組所有元素的個(gè)數(shù) foreach(int i in intArray);for(int i = 0;i < intArray.GetLength(0);i++);//Array.GetLength(0)返回?cái)?shù)組第一維的個(gè)數(shù) 2)多維數(shù)組 for(int i = 0;i < int3Array.GetLength(0);i++)//遍歷三維數(shù)組 for(int j = 0;j < int3Array.GetLength(1);j++) for(int k = 0;k < int3Array.GetLength(2);k++) { ...} 數(shù)組的維數(shù)就是該數(shù)組的秩(Rank)。Array.Rank可以返回?cái)?shù)據(jù)的秩。鋸齒數(shù)組(jagged Array)是元素為數(shù)組的數(shù)組,例: int[][] jaggedArray = new int[2][];//包含二個(gè)元素,每個(gè)元素是個(gè)數(shù)組 jaggedArray[0] = new int[2];//每個(gè)元素必須初始化 jaggedArray[1] = new int[3];for(int i = 0;i < jaggedArray.Length;i++)//遍歷鋸齒數(shù)組 for(int j = 0;j < jaggedArray[i].Length;j++) { ...} 類的屬性稱為智能字段,類的索引器稱為智能數(shù)組。由于類本身作數(shù)組使用,所以用this作索引器的名稱,索引器有索引參數(shù)值。例: using System;using System.Collections;class MyListBox { protected ArrayList data = new ArrayList(); public object this[int idx] //this作索引器名稱,idx是索引參數(shù) { get { if(idx >-1 && idx < data.Count) { return data[idx]; } else { return null; } } set { if(idx >-1 && idx < data.Count) { data[idx] = value; } else if(idx = data.Count) { data.Add(value); } else { //拋出一個(gè)異常 } } } } 接口是二段不同代碼之間約定,通過約定實(shí)現(xiàn)彼此之間的相互訪問。C#并不支持多繼承,但通過接口可實(shí)現(xiàn)相同功能。當(dāng)在接口中指定了實(shí)現(xiàn)這個(gè)接口的類時(shí),我們就稱這個(gè)類“實(shí)現(xiàn)了該接口”或“從接口繼承”。一個(gè)接口基本上就是一個(gè)抽象類,這個(gè)抽象類中除了聲明C#類的其他成員類型——例如屬性、事件和索引器之外,只聲明了純虛擬方法。接口中可以包含方法、屬性、索引器和事件——其中任何一種都不是在接口自身中來實(shí)現(xiàn)的。例: interface IExampleInterface { //property declaration int testProperty { get;} //event declaration event testEvevnt Changed; //mothed declaration function void testMothed(); //indexer declaration string this[int index] { get;set;} } 說明:定義接口時(shí),在方法、屬性、事件和索引器所有這些接口成員都不能用public之類的訪問限定符,因?yàn)樗薪涌诔蓡T都是public類型的。因?yàn)榻涌诙x了一個(gè)約定,任何實(shí)現(xiàn)一個(gè)接口的類都必須定義那個(gè)接口中每一個(gè)成員,否則將編譯失敗。例: using System;public class FancyControl { protected string data; public string Data { get {return this.data;} set {data = value;} } } interface IValidate { bool Validate();//接口方法 } public class MyControl: FancyControl, IValidate { public MyControl() { data = “my control data”; } public bool Validate()//實(shí)現(xiàn)接口 { if(data == “my control data”) return true; else return false; } } class InterfaceApp { MyControl myControl = new MyControl(); IValidate val =(IValidate)myControl;//可以將一個(gè)實(shí)現(xiàn)某接口的類,轉(zhuǎn)換成該接口 bool success = val.Validate();//然后可調(diào)用該接口的方法 } 也可以用:bool success = myControl.Validate();這種方法來調(diào)用Validate方法,因?yàn)閂alidate在類MyControl中是被定義成public的,如果去除public,Validate方法被隱藏,就不能用這種方法調(diào)用了,這樣隱藏接口方法稱為名字隱藏(name hiding)。可以用:類實(shí)例 is 接口名 來判斷某個(gè)類是否實(shí)現(xiàn)了某接口,例: myControl is IValidate //MyControl類的實(shí)例myControl是否實(shí)現(xiàn)了IValidate接口 當(dāng)然,也可用as來作轉(zhuǎn)換,根據(jù)轉(zhuǎn)換結(jié)果是否為null來判斷某個(gè)類是否實(shí)現(xiàn)了某接口,例: IValidate val = myControl as IValidate;if(null == val){...//沒有實(shí)現(xiàn)IValidate接口 } else {...//實(shí)現(xiàn)了IValidate接口 } 如果一個(gè)類從多個(gè)接口繼承,而這些接口中如果定義的同名的方法,則實(shí)現(xiàn)接口的方法時(shí),必須加接口名來區(qū)別,寫成 接口名.方法名。假設(shè)Test類從IDataStore和ISerializable二個(gè)接口繼承,而這二個(gè)接口都有SaveData()方法,實(shí)現(xiàn)SaveData()方法時(shí)必須寫成: class Test: ISerializable, IDataStore { void ISerializable.SaveData() { ...} void IDataStore.SaveData() { ...} } 如果一個(gè)類從多個(gè)接口繼承,為了方便可以定義一個(gè)新的接口,這個(gè)接口繼續(xù)多個(gè)接口,然后類直接從這個(gè)接口繼承就可以了,這個(gè)叫合并接口。例: interface ISaveData: ISerializable, IDataStore { //不需要定義任何方法或成員,只是用作合并 } class Test: ISaveData //只要繼承ISaveData就可以了 {...} C# 操作符優(yōu)先級(jí)(從高到低) 初級(jí)操作符()x.y f(x)a[x] x++ x--new typeof sizeof checked unchecked 一元操作符 +位移操作符 << >> 關(guān)系操作符 < > <= >= is 等于操作符 == 邏輯與 & 邏輯異或 ^ 邏輯或 | 條件與 && 條件或 || 條件操作符 ?: 賦值操作符 = *= /= %= +=-= <<= >>= &= ^= |= 所有的二元操作符除賦值符外都是左聯(lián)合的,即從左到右計(jì)算。 typeof()運(yùn)算符可以從一個(gè)類名得到一個(gè)System.Type對象,而從System.Object對象繼承來的GetType()方法則可從一個(gè)類實(shí)例來得到一個(gè)System.Type對象。例: Type t1 = typeof(Apple);//Apple是一個(gè)類名 Apple apple = new Apple();//apple是Apple類的一個(gè)實(shí)例 Type t2 = apple.GetType();//t1與t2是相同的 通過反射得到一個(gè)類的所有成員和方法: Type t = typeof(Apple);string className = t.ToString();//得到類名 MethodInfo[] methods = t.GetMethods();//得到所有方法 foreach(MethodInfo method in methods){ //用method.ToString()得到方法名 } MemberInfo[] members = t.GetMembers();//得到所有成員 foreach(MemberInfo member in members){ //用member.ToString()得到成員名 } sizeof()操作符用來計(jì)算值類型變量在內(nèi)存中占用的字節(jié)數(shù)(Bytes),并且它只能在unsafe(非安全) 代碼中使用。例: static unsafe public void ShowSizes(){ int i, j; j = sizeof(short); j = sizeof(i);} 盡可能使用復(fù)合賦值操作符,它比不用復(fù)合賦值操作符的效率高。for語句的語法為: for(initialization;Boolean-expression;step) embedded-statement 在initialization和step部份還可以使用逗號(hào)操作符,例: for(int i = '0', j = 1;i <= 'xFF';i++, j++)for(int i = 1, j = 1;i < 1000;i += j, j = i!~ ++--true false 二元:+32)/ 9)* 5; } } 代表的(delegate)目的與C++中的函數(shù)指針相同,代表不是在編譯時(shí)被定義的,而是在運(yùn)行時(shí)被定義的。 代表主要有二個(gè)用途:回調(diào)(Callback)和事件處理(event)回調(diào)通常用于異步處理和自定義處理。例: class DBManager { static DBConnection[] activeConnections; //聲明回調(diào)函數(shù) public void delegate EnumConnectionCallback(DBConnection connection); public static void EnumConnections(EnumConnectionCallback callback) { foreach(DBConnection connection in activeConnections) { callback(connection);//執(zhí)行回調(diào)函數(shù) } } } //調(diào)用 class DelegateApp { public static void ActiveConncetionCallback(DBConnection connection)//處理函數(shù) { ...} public void main() { //創(chuàng)建指向具體處理函數(shù)的代表實(shí)例(新建一個(gè)代表,讓它指向具體的處理函數(shù)) DBManager.EmnuConnectionCallback myCallback = new DBManager.EmnuConnectionCallback(ActiveConncetionCallback); DBManager.EnumConnections(myCallback); } } //使用靜態(tài)代表,上面的調(diào)用改為 class DelegateApp { //創(chuàng)建一個(gè)指向處理函數(shù)的靜態(tài)代表 public static DBManager.EmnuConnectionCallback myCallback = new DBManager.EmnuConnectionCallback(ActiveConncetionCallback); public static void ActiveConncetionCallback(DBConnection connection) {...} public void main() { DBManager.EnumConnections(myCallback); } } //在需要時(shí)才創(chuàng)建代表,上面的調(diào)用改為 class DelegateApp { //將創(chuàng)建代表放在屬性的getter方法中 public static DBManager.EmnuConnectionCallback myCallback { get { retun new DBManager.EmnuConnectionCallback(ActiveConncetionCallback); } } public static void ActiveConncetionCallback(DBConnection connection) {...} public void main() { DelegateApp app = new DelegateApp();//創(chuàng)建應(yīng)用程序 DBManager.EnumConnections(myCallback); } } 可以將多個(gè)代表整合成單個(gè)代表,例: class CompositeDelegateApp { public static void LogEvent(Part part) { ...} public static void EmailPurchasingMgr(Part part) { ...} public static void Main() { //定義二個(gè)代表 InventoryManager.OutOfStockExceptionMethod LogEventCallback = new InventoryManager.OutOfStockExceptionMethod(LogEvent); InventoryManager.OutOfStockExceptionMethod EmailPurchasingMgrCallback = new InventoryManager.OutOfStockExceptionMethod(EmailPurchasingMgr); //整合為一個(gè)代表,注意后加的代表先執(zhí)行(這里是先執(zhí)行LogEventCallback) InventoryManager.OutOfStockExceptionMethod onHandExceptionEventsCallback = EmailPurchasingMgrCallback + LogEventCallback; //調(diào)用代表 InventoryManager mgr = new InventoryManager(); mgr.ProcessInventory(onHandExceptionEventsCallback); //InventoryManager類的ProcessInventory方法的原型為: //public void ProcessInventory(OutOfStockExceptionMethod exception); } } 可以根據(jù)需要將多個(gè)代表自由地組合成單個(gè)代表,例: class CompositeDelegateApp { //代表指向的處理函數(shù)(三個(gè)代表三個(gè)函數(shù)) public static void LogEvent(Part part) { ...} public static void EmailPurchasingMgr(Part part){...} public static void EmailStoreMgr(Part part) { ...} public static void Main() { //通過數(shù)組定義三個(gè)代表 InventoryManager.OutOfStockExceptionMethod[] exceptionMethods = new InventoryManager.OutOfStockExceptionMethod[3]; exceptionMethods[0] = new InventoryManager.OutOfStockExceptionMethod(LogEvent); exceptionMethods[1] = new InventoryManager.OutOfStockExceptionMethod(EmailPurchasingMgr); exceptionMethods[2] = new InventoryManager.OutOfStockExceptionMethod(EmailStoreMgr); int location = 1; //再定義一個(gè)代表(用于組合成單代表) InventoryManager.OutOfStockExceptionMethod compositeDelegate; //根據(jù)需要組合 if(location = 2) { compositeDelegate = exceptionMethods[0] + exceptionMethods[1]; } else { compositeDelegate = exceptionMethods[0] + exceptionMethods[2]; } //調(diào)用代表 InventoryManager mgr = new InventoryManager(); mgr.ProcessInventory(compositeDelegate); } } C#的事件遵循“發(fā)布——預(yù)訂”的設(shè)計(jì)模式。在這種模式中,一個(gè)類公布能夠出現(xiàn)的所有事件,然后任何的類都可以預(yù)訂這些事件。一旦事件產(chǎn)生,運(yùn)行環(huán)境就負(fù)責(zé)通知每個(gè)訂戶事件已經(jīng)發(fā)生了。 當(dāng)代表作為事件的處理結(jié)果時(shí)(或者說定義具有代表的事件),定義的代表必須指向二個(gè)參數(shù)的方法:一個(gè)參數(shù)是引發(fā)事件的對象(發(fā)布者),另一個(gè)是事件信息對象(這個(gè)對象必須從EventArgs類中派生)。例: using System; class InventoryChangeEventArgs: EventArgs //事件信息對象,從EventArgs類派生 {...//假設(shè)定義二個(gè)public屬性string Sku和int Change } class InventoryManager //事件的發(fā)布者 { //聲明代表 public delegate void InventoryChangeEventHander(object source, InventoryChangeEventArgs e); //發(fā)布事件,event關(guān)鍵字可將一個(gè)代表指向多個(gè)處理函數(shù) public event InventoryChangeEventHandler onInventoryChangeHander; public void UpdateInventory(string sku, int change) { if(change == 0) return; InventoryChangeEventArgs e = new InventoryChangeEventArgs(sku, change); //觸發(fā)事件 if(onInventoryChangeHandler!= null)//如果有預(yù)訂者就觸發(fā) onInventoryChangeHandler(this, e);//執(zhí)行代表指向的處理函數(shù) } } class InventoryWatcher //事件的預(yù)訂者 { public InventoryWatcher(InventoryManager mgr)//mgr參數(shù)用于聯(lián)結(jié)發(fā)布者 { this.inventoryManager = mgr; //預(yù)訂事件,用 += 調(diào)用多個(gè)處理函數(shù) mgr.onInventroyChangeHandler += new InventoryManager.InventoryChangeEventHandler(onInventoryChange); //事件處理函數(shù) void onInventroyChange(object source, InventroyChangeEventArgs e) { ...} InventoryManager inventoryManager; } } class EventsApp //主程序 { public static void Main() { InventoryManager inventoryManager = new InventoryManager(); InventoryWatcher inventoryWatcher = new InventoryWatcher(inventoryManager); inventoryManager.UpdateInventory(“111 006 116”,-2); inventoryManager.UpdateInventory(“111 006 116”, 5); } } Microsoft Windows NT和IBM OS/2等操作系統(tǒng)都支持占先型多任務(wù)。在占先型多任務(wù)執(zhí)行中,處理器負(fù)責(zé) 給每個(gè)線程分配一定量的運(yùn)行時(shí)間——一個(gè)時(shí)間片(timeslice)。處理器接著在不同的線程之間進(jìn)行切換,執(zhí)行相應(yīng)的處理。在單處理器的計(jì)算機(jī)上,并不能真正實(shí)現(xiàn)多個(gè)線程的同時(shí)運(yùn)行,除非運(yùn)行在多個(gè)處理器 的計(jì)算機(jī)上。操作系統(tǒng)調(diào)度的多線程只是根據(jù)分配給每個(gè)線程時(shí)間片進(jìn)行切換執(zhí)行,感覺上就像同時(shí)執(zhí)行。 上下文切換(context switching)是線程運(yùn)行的一部分,處理器使用一個(gè)硬件時(shí)間來判斷一個(gè)指定線程的時(shí)間片何時(shí)結(jié)束。當(dāng)這個(gè)硬件計(jì)時(shí)器給出中斷信號(hào)時(shí),處理器把當(dāng)前運(yùn)行的線程所用的所有寄存器(registers)數(shù)據(jù)存儲(chǔ)到堆棧中。然后,處理器把堆棧里那些相同的寄存器信息存放到一種被稱為“上下文結(jié)構(gòu)”的數(shù)據(jù)結(jié)構(gòu)中。當(dāng)處理器要切換回原來執(zhí)行的線程時(shí),它反向執(zhí)行這個(gè)過程,利用與該線程相關(guān)的上下文結(jié)構(gòu),在寄存器里重新恢復(fù)與這一線程相關(guān)的信息。這樣的一個(gè)完整過程稱為“上下文切換”。多線程允許應(yīng)用程序把任務(wù)分割為多個(gè)線程,它們彼此之間可以獨(dú)立地工作,最大限度地利用了處理器時(shí)間。using System;using System.Threading;class SimpleThreadApp { public static void WorkerThreadMethod()//線程的執(zhí)行體 { ...//執(zhí)行一些操作 } public static void Main() { //創(chuàng)建一個(gè)線程代表指向線程的執(zhí)行體,ThreadStart是創(chuàng)建新線程必須用到的代表 ThreadStart worker = new ThreadStart(WorkerThreadMethod); Thread t = new Thread(worker);//用線程代表創(chuàng)建線程 t.Start(); //執(zhí)行線程 } } 可以通過兩種方式來得到一個(gè)Thread對象:一種是通過創(chuàng)建一個(gè)新線程來得到,如上例;另一種在正在執(zhí)行的線程調(diào)用靜態(tài)的Thread.CurrentThread方法。 靜態(tài)方法Thread.Sleep(int ms)可以讓當(dāng)前線程(它自動(dòng)調(diào)用Thread.CurrentThread)暫停指定毫秒的時(shí)間。 如果使用Thread.Sleep(0)那么當(dāng)前線程將一直處于等待中,直到另一個(gè)線程調(diào)用這個(gè)線程的實(shí)例方法Thread.Interrupt方法,等待才會(huì)結(jié)束。使用Thread.Suspend方法也能掛起線程,Thread.Suspend方法可以被當(dāng)前線程或其他線程調(diào)用,而Thread.Sleep(0)只能由當(dāng)前線程在執(zhí)行體中調(diào)用。當(dāng)線程用Thread.Suspend掛起時(shí),必須用Thread.Resume方法恢復(fù)。不論Thread.Suspend方法調(diào)用了多少次,只要調(diào)用Thread.Resume方法一次就可以線程恢復(fù)執(zhí)行。用Thread.Suspend方法并不會(huì)阻塞線程,調(diào)用立即返回。而Thread.Sleep(0)則會(huì)阻塞線程。所以確切地說Thread.Sleep(0)暫停線程,而不是掛起線程。 使用Thread.Abort方法可以終止正在執(zhí)行的線程。當(dāng)Thread.Abort方法被調(diào)用時(shí),線程不會(huì)立即終止執(zhí)行。運(yùn)行環(huán)境將會(huì)等待,直到線程到達(dá)文檔中所描述的“安全點(diǎn)”。如果要確保線程已經(jīng)完全停止,可以使用Thread.Join方法。這是一個(gè)同步調(diào)用,同步調(diào)用意味著直到線程完全停止,調(diào)用才會(huì)返回。 Thread.Priority屬性用于設(shè)置的線程的優(yōu)先級(jí)。其值是Thread.ThreadPriority枚舉值,可以設(shè)為Highest, AboveNormal,Normal, BelowNormal, Lowest。缺省值是Thread.ThreadPriority.Normal。 線程的同步是為了解決多個(gè)線程同時(shí)使用同一對象產(chǎn)生的一些問題。通過同步,可以指定代碼的臨界區(qū)(critical section),一次只有一個(gè)線程可以進(jìn)入臨界區(qū)。使用System.Monitor類(鎖定與信號(hào)量)進(jìn)行線程同步: using System;using System.Threading;public void SaveData(string text)//線程執(zhí)行函數(shù)或線程執(zhí)行函數(shù)調(diào)用的對象的方法 { ...//執(zhí)行其他一些不需要同步的處理 Monitor.Enter(this);//獲取對象的Monitor鎖 ...//執(zhí)行需要同步的處理 Monitor.Exit(this);//釋放對象的Monitor鎖 ...//執(zhí)行其他一些不需要同步的處理 } 說明:當(dāng)執(zhí)行Monitor.Enter方法時(shí)。這個(gè)方法會(huì)試圖獲取對象上的Monitor鎖,如果另一個(gè)線程已經(jīng)擁有了這個(gè)鎖,這個(gè)方法將會(huì)阻塞(block),直到這個(gè)鎖被釋放。 也可用C#的lock語句來獲得和釋放一個(gè)Monitor鎖。上面同步寫成:public void SaveData(string text)//線程執(zhí)行函數(shù)或線程執(zhí)行函數(shù)調(diào)用的對象的方法 { ...//執(zhí)行其他一些不需要同步的處理 lock(this)//獲取對象的Monitor鎖,代碼塊執(zhí)行完成后釋放Monitor鎖 { ...//執(zhí)行需要同步的處理 } ...//執(zhí)行其他一些不需要同步的處理 } 也可以使用System.Threading名稱空間的Mutex類(互斥類)進(jìn)行線程同步。與Monitor鎖一樣,一次只有一個(gè)線程能獲得一個(gè)給定的互斥。但Mutex要慢得多,但它增加了靈活性。例: using System;using System.Threading;class Database { Mutex mutex = new Mutex(false);//創(chuàng)建一個(gè)互斥,但不立即獲得它 //注意:創(chuàng)建互斥在需要同步的方法之外,實(shí)際上它只要?jiǎng)?chuàng)建一個(gè)實(shí)例 public void SaveData(string text)//需要同步的方法 { mutex.WaitOne();//等待獲得互斥 ...//需要同步的處理 mntex.Close();//釋放互斥 } } Mutex類重載了三個(gè)構(gòu)造函數(shù): Mutex() //創(chuàng)建并使創(chuàng)建類立即獲得互斥 Mutex(bool initiallyOwned) //創(chuàng)建時(shí)可指定是否要立即獲得互斥 Mutex(bool initiallyOwned, string muterName)//還可以指定互斥的名稱 Mutex.WaitOne方法也重載了三次: Mutex.WaitOne() //一直等待 Mutex.WaitOne(TimeSpan time, bool exitContext)//等待TimeSpan指定的時(shí)間 Mutex.WaitOne(int milliseconds, bool exitContext)//等待指定的毫秒 線程的用法: 1)并發(fā)操作:比如一個(gè)程序監(jiān)視多個(gè)COM口,當(dāng)每個(gè)COM接到信息時(shí)執(zhí)行一段處理時(shí)。2)復(fù)雜長時(shí)間操作:一個(gè)長時(shí)間的復(fù)雜操作可能會(huì)使界面停滯,停止用戶響應(yīng),如果還允許用戶停止它,或者顯示進(jìn)度條、顯示操作執(zhí)行進(jìn)程信息時(shí)。 反射(Reflection)就是能夠在運(yùn)行時(shí)查找類型信息,這是因?yàn)?NET編譯的可執(zhí)行(PE)文件中包括MSIL和元數(shù)據(jù)(metadata)。 反射的中心是類System.Type。System.Type是一個(gè)抽象類,代表公用類型系統(tǒng)(Common Type System, CTS)中的一種類型。 using System;using System.Reflection;//反射命名空間,必須引用 public static void Main(string[] args){ int i = 6; Type t = i.GetType(); //根據(jù)實(shí)例得到類型 t = Type.GetType(“System.Int32”);//根據(jù)類型的字符名稱得到類型 } 通過Assembly類可以得到已經(jīng)編譯.NET Framework程序的中所有類型,例: using System;using System.Diagnostics;//為了使用Process類 using System.Reflection;//為了使用Assembly類 class GetTypesApp { protected static string GetAssemblyName(string[] args) { string assemblyName; if(0 == args.Length)//如果參數(shù)為空,取當(dāng)前進(jìn)程的名稱 { Process p = Process.GetCurrentProcess(); assemblyName = p.ProcessName + “.exe”; } else assemblyName = args[0];//取第一個(gè)參數(shù),即當(dāng)前運(yùn)行程序名 return assemblyName; } public static void Main(string[] args) { string assemblyName = GetAssemblyName(args); Assembly a = Assembly.LoadFrom(assemblyName);//調(diào)用編譯程序集 Type[] types = a.GetTypes(); //得到多個(gè)類型 foreach(Type t in types) //遍歷類型數(shù)組 { ...//取得t.FullName,t.BaseType.FullName等類型信息 } } } 一個(gè)應(yīng)用程序可以包括多個(gè)代碼模塊。若要將一個(gè)cs文件編譯一個(gè)模塊,只要執(zhí)行下面的命令: csc /target:module 要編譯的模塊.cs //csc是C Sharp Compiler(C#編譯器)然后在應(yīng)用程序中using編譯的模塊.cs中的NameSpace即可應(yīng)用了。要反射應(yīng)用程序中所有代碼模塊(Module),只要: Assembly a = Assembly.LoadFrom(assemblyName);//應(yīng)用程序的物理文件名 Module[] modules = a.GetModules();foreach(Module m in modules){...//顯示m.Name等 } 后期綁定(latebinding),例: string[] fileNames = Directory.GetFiles(Environment.CurrentDirectory, “*.dll”);foreach(string fileName in fileNames){ Assembly a = Assembly.LoadFrom(fileName); Type[] types = a.GetTypes(); foreach(Type t in types) { if(t.IsSubclassOf(typeof(CommProtocol)))//判斷是否有CommProtocol的派生類 { object o = Activator.CreateInstance(t);//生成實(shí)例 MethodInfo mi = t.GetMethod(“DisplayName”); mi.Invoke(o, null); //調(diào)用方法 } } } //帶參數(shù)的例子 namespace Programming_CSharp { using System; using System.Reflection; public class Tester { public static void Main() { Type t = Type.GetType(“System.Math”); Object o = Activator.CreateInstance(t); // 定義參數(shù)類型 Type[] paramTypes = new Type[1]; paramTypes[0]= Type.GetType(“System.Double”); MethodInfo CosineInfo = t.GetMethod(“Cos”, paramTypes); //設(shè)置參數(shù)數(shù)據(jù) Object[] parameters = new Object[1]; parameters[0] = 45; //執(zhí)行方法 Object returnVal = CosineInfo.Invoke(o, parameters); Console.WriteLine(“The cosine of a 45 degree angle {0}”, returnVal); } } } 動(dòng)態(tài)生成代碼和動(dòng)態(tài)調(diào)用的完整例子: //動(dòng)態(tài)生成代碼的部分 using System;using System.Reflection;using System.Reflection.Emit;//動(dòng)態(tài)生成代碼必須引用 namespace ILGenServer { public class CodeGenerator { public CodeGenerator() { currentDomain = AppDomain.CurrentDomain;//得到當(dāng)前域 assemblyName = new AssemblyName();//從域創(chuàng)建一個(gè)程序集 assemblyName.Name = “TempAssembly”; //得到一個(gè)動(dòng)態(tài)編譯生成器,AssemblyBuilerAccess.Run表示只在內(nèi)存中運(yùn)行,不能保存 assemblyBuilder = currentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilerAccess.Run); //從編譯生成器得到一個(gè)模塊生成器 moduleBuilder = assemblyBuilder.DefineDynamicModule(“TempModule”); //模塊生成器得到類生成器 typeBuilder = moduleBuilder.DefineType(“TempClass”, TypeAttributes.Public); //為類添加一個(gè)方法 methodBuilder = typeBuilder.DefineMethod(“HelloWord”, MethodAttributes.Public, null, null); //為方法寫入代碼,生成代碼必須使用到IL生成器 msil = methodBuilder.GetILGenerator(); msil.EmitWriteLine(“Hello World”);msil.Emit(OpCodes.Ret);//最后還需要編譯(build)一下類 t = typeBuilder.CreateType(); } AppDomain currentDomain; AssemblyName assemblyName; AssemblyBuilder assemblyBuilder; ModuleBuilder moduleBuilder; TypeBuilder typeBuilder; MethodBuilder methodBuilder; ILGenerator msil; object o; Type t; public Type T { get { return this.t; } } } } //動(dòng)態(tài)調(diào)用的部分 using System;using System.Reflection;using ILGenServer;//引用動(dòng)態(tài)生成代碼的類 public class ILGenClientApp { public static void Main({ CodeGenerator gen = new CodeGenerator();//創(chuàng)建動(dòng)態(tài)生成類 Type t = gen.T; if(null!= t) { object o = Activator.CreateInstance(t); MethodInfo helloWorld = t.GetMethod(“HelloWorld”);//為調(diào)用方法創(chuàng)建一個(gè)MethodInfo if(null!= helloWorld) { helloWorld.Invoke(o, null);//調(diào)用方法 } } } } 調(diào)用DLL using System;using System.Runtime.InteropServices;//為了使用DLLImport特性 class PInvokeApp { [DllImport(“user32.dll”, CharSet=CharSet.Ansi)] //CharSet.Ansi指定Ansi版本的函數(shù)(MessageBoxA),CharSet.Unicode指定Unicode版本的函數(shù)(MessageBoxW) static extern int MessageBox(int hWnd, string msg, string caption, int type);//聲明DLL中的函數(shù) //[DllImport(“user32.dll”, EntryPoint=“MessageBoxA”)] //用這種方法使用不同的函數(shù)名 //static extern int MsgBox(int hWnd, string msg, string caption, int type); //[DllImport(“user32.dll”, CharSet=CharSet.Unicode)] //調(diào)用Unicode版的DLL函數(shù) //static extern int MessageBox(int hWnd, [MarshalAs(UnmanagedType.LPWStr)]string msg,// [MarshalAs(UnmanagedType.LPWStr)]string caption, int type);//將LPWStr翻譯為string型,缺省情況系統(tǒng)只將LPStr翻譯成string public static void Main() { MessageBox(0, “Hello, World!”, “CaptionString”, 0);//調(diào)用DLL中的函數(shù) } } 例2,使用回調(diào): class CallbackApp { [DllImport(“user32.dll”)] static extern int GetWindowText(int hWnd, StringBuilder text, int count); delegate bool CallbackDef(int hWnd, int lParam); [DllImport(“user32.dll”)] static extern int EnumWindows(CallbackDef callback, int lParam); static bool PrintWindow(int hWnd, int lParam) { StringBuilder text = new StringBuilder(255); GetWindowText(hWnd, text, 255); Console.WriteLine(“Window Caption: {0}”, text); return true; } static void Main() { CallbackDef callback = new CallbackDef(PrintWindow); EnumWindows(callback, 0); } } 關(guān)鍵字unsafe指定標(biāo)記塊在非控環(huán)境中運(yùn)行。該關(guān)鍵字可以用于所有的方法,包括構(gòu)造函數(shù)和屬性,甚至還有方法中的代碼塊。關(guān)鍵字fixed負(fù)責(zé)受控對象的固定(pinning)。Pinning是一種動(dòng)作,向垃圾收集(Garbage Collector, GC)指定一些不能被移動(dòng)的對象。為了不在內(nèi)存中產(chǎn)生碎片,.NET運(yùn)行環(huán)境把對象四處移動(dòng),以便于最有效地利用內(nèi)存。使用fixed后指定對象將不會(huì)被移動(dòng),所以就可以用指針來訪問它。 C#中只能得到值類型、數(shù)組和字符串的指針。在數(shù)組的情況下,第一個(gè)元素必須是值類型,因?yàn)镃#實(shí)際上是返回一個(gè)指向數(shù)組第一個(gè)元素的指針,而不是返回?cái)?shù)組自身。& 取一個(gè)變量的內(nèi)存地址(即指向該變量的指針)* 取指針?biāo)缸兞康闹?> 取成員 例:using System;class UnsafeApp { public static unsafe void GetValues(int* x, int* y) { *x = 6; *y = 42; } public static unsafe void Main() { int a = 1; int b = 2; GetValues(&a, &b); } } fixed語法為:fixed(type* ptr = expression)statements其中type也可以為非控類型,也可是void;expression是任何產(chǎn)生一個(gè)type指針的表達(dá)式;statements是應(yīng)用的代碼塊。例: fixed(int* f = &foo.x)//foo是Foo類的一個(gè)實(shí)例,x是Foo類的一個(gè)int屬性 { SetFooValue(f);//SetFooValue方法的定義為unsafe static void SetFooValue(int* x)} 傳統(tǒng)的COM組件可以通過互操作層(COM Interop)與.NET運(yùn)行環(huán)境交互。互操作層處理在托管運(yùn)行環(huán)境和非托管區(qū)域中的COM組件操作之間傳遞所有的消息。 要使COM組件能在.NET環(huán)境中使用,必須為COM組件生成元數(shù)據(jù)。.NET運(yùn)行環(huán)境用元數(shù)據(jù)層業(yè)判斷類型信息。在運(yùn)行時(shí)刻使用類型信息,以便生成RCW(Runtime Callable Wrapper,運(yùn)行時(shí)可調(diào)用包裝)。當(dāng).NET應(yīng)用程序與COM對象交互時(shí),RCW處理對COM對象的裝載和調(diào)用。RCW還完成許多其他的工作,如管理對象標(biāo)識(shí)、對象生存周期以及接口緩沖區(qū)。對象生存周期管理十分關(guān)鍵,因?yàn)?NET GC把對象到處移動(dòng),并且當(dāng)對象不再使用時(shí),自動(dòng)處理這些對象。RCW服務(wù)告訴.NET,應(yīng)用程序正與托管.NET組件交互,同時(shí)又使非托管COM組件“覺得”COM對象是被傳統(tǒng)的COM客戶端調(diào)用的。 為了為COM組件生成元數(shù)據(jù)包裝,必須使用tlbimp.exe(TypeLib Importer)工具: tlbimp some_COM.tlb /out:som_COM.dll 1、.NET平臺(tái)包括.NET框架和.NET開發(fā)工具等組成部分。.NET框架是整個(gè)開發(fā)平臺(tái)的基礎(chǔ),包括公共語言運(yùn)行庫和.NET類庫。.NET開發(fā)工具包括Visual Studio.NET集成開發(fā)環(huán)境和.NET編程語言。.NET框架(.NET Framework)是.NET開發(fā)平臺(tái)的基礎(chǔ)。.NET框架提供了一個(gè)跨語言的、統(tǒng)一的、面向?qū)ο蟮拈_發(fā)和運(yùn)行環(huán)境。 2、在Visual Studio.NET集成開發(fā)環(huán)境下,可以開發(fā)多種不同類型的應(yīng)用程序。最常見的有以下幾種。 。控制臺(tái)應(yīng)用程序 。Windows應(yīng)用程序 。ASP.NET網(wǎng)站 3、開發(fā)和運(yùn)行控制臺(tái)應(yīng)用程序 創(chuàng)建一個(gè)控制臺(tái)應(yīng)用程序,主要包含以下步驟: (1)執(zhí)行文件—》新建—》項(xiàng)目 (2)打開“新建項(xiàng)目”對話框,在“項(xiàng)目類型”列表中選擇Visual c#節(jié)點(diǎn)下的Windows,在“模板”窗格中選擇“控制臺(tái)應(yīng)用程序”項(xiàng)目模板,輸入項(xiàng)目的名稱、位置及 解決方案名稱后,單擊“確定”按鈕。 (3)在打開的.cs文件中編寫代碼。 (4)運(yùn)行程序。執(zhí)行“調(diào)試”—》啟動(dòng)調(diào)試菜單命令,編譯并運(yùn)行程序 4、c#程序的基本結(jié)構(gòu) 。using關(guān)鍵字的功能是用于導(dǎo)入其它命名空間中定義的類型,包括.NET類庫。例如,代碼中使用的console.readline方法實(shí)際上是一個(gè)簡寫,其全稱是system.console.readline,但由于在代碼的開始使用using指令引入了system命名空間,所以后面可以直接使用console.readline來進(jìn)行輸入。 。namespace 即“命名空間”,也稱“名稱空間”。命名空間是Visual Studio.NET中的各種語言使用的一種代碼組織的形式,當(dāng)編譯一個(gè)解決方案時(shí),系統(tǒng)會(huì)用項(xiàng)目名稱做名字,生成一個(gè)namespace,并把類都放在這個(gè)namespace里面。 集合聲明:類B可以換成任意object對象 1、CollectionBase 類A繼承CollectionBase類,通過CollectionBase的成員List實(shí)現(xiàn)類A的Add(類 B)、Remove(類B)和RemoveAt(類B)方法: publicvoidAdd(類B newB) {List.Add(newB);} publicvoidRemove(類B newB) {List.Remove(newB);} publicvoidRemoveAt(int index) {List.RemoveAt(index);} 在類A中建立索引可以按類似數(shù)組的方法訪問。 public 類B this[int index] {get{return(類B)List[index];} set{List[index]=value;} } 利用CollectionBase的成員InnerList(ArrayList對象)實(shí)現(xiàn)類A的Contains()方法: publicboolContains(類B newB) { returnInnerList.Contains(newB); } 注意:InnerList是ArrayList類實(shí)例,其Contains方法通過調(diào)用Object.Equals確定相等性,Equals默認(rèn)實(shí)現(xiàn)僅支持引用相等。對于引用類型,相等定義為對象相等,即這些引用是否引用同一對象。對于值類型,相等定義為按位相等。 可以在類B中重寫Object.Equals方法和GetHashCode()方法。publicoverrideboolEquals(objectobj) {//Check for null and compare run-time types.if(obj == null || GetType()!= obj.GetType())returnfalse; B b =(B)obj; return(比較邏輯); } publicoverrideintGetHashCode(){??} 2、DictionaryBase 類A繼承DictionaryBase類,通過DictionaryBase的成員 Dictionary(IDictionary類型的接口),實(shí)現(xiàn)類A的 Add(object key,類B)和Remove(object key,類B)方法: publicvoidAdd(object key,類B newB) {Dictionary.Add(key,newB);} publicvoidRemove(object key,類B newB) {Dictionary.Remove(key,newB);} 在類A中建立索引可以按類似數(shù)組的方法訪問。 public 類B this[object index] {get{return(類B)Dictionary[index];} set{Dictionary[index]=value;} } 利用DictionaryBase的接口成員Dictionary實(shí)現(xiàn)類A的Contains()方法: publicboolContains(object key) { returnDictionary.Contains(key); } 3、迭代器 對于繼承CollectionBase類的A,使用 foreach(BsourceBin類A對象){} 對于繼承DictionaryBase類的A,使用 foreach(DictionaryEntrysourceBin類A對象){source.Value.} 對于類迭代,使用方法GetEnumerator(),返回類型是IEnumerator;類成員迭代使用IEnumerable(),返回類型是IEnumerable; 例如繼承DictionaryBase類的A的迭代器,public new IEnumeratorGetEnumerator() {foreach(object b in Dictionary.Values) yield return(B)b; } 以后使用foreach循環(huán)時(shí),可按照類似繼承CollectionBase類的的方式使用。 4、淺度復(fù)制與深度復(fù)制 淺度復(fù)制:簡單地按照成員復(fù)制對象可以通過派生于System.Object的MemberwiseClone()方法來完成,這是一個(gè)受保護(hù)的方法,但是很容易在對象上定義一個(gè)調(diào)用該方法的公共方法例如GetCopy()。這個(gè)方法的復(fù)制功能成為淺復(fù)制。淺拷貝是對引用類型拷貝地址,對值類型直接進(jìn)行拷貝,但是string類例外,因?yàn)閟tring是readonly的,當(dāng)改變string類型的數(shù)據(jù)值時(shí),將重新分配了內(nèi)存地址。數(shù)組、類也是淺度復(fù)制,而結(jié)構(gòu)體、數(shù)值型、枚舉是深度復(fù)制。 深度復(fù)制:需要深度復(fù)制的類A添加ICloneable接口,實(shí)現(xiàn)該接口的Clone()方法。 public object Clone() {A newA=new A(); object []arr=new object[維度];//object 可以是數(shù)值類型,string //不能使用newA.arr=arr;因?yàn)橥ㄟ^數(shù)組名賦值引用同一地址,是淺度復(fù)制 arr.CopyTo(newA.arr,0); returnnewA;} 假設(shè)類A中有成員對象類B實(shí)例myB,則在類B定義中也要實(shí)現(xiàn)ICloneable的Clone()方法,class B:ICloneable { public object Clone(){??} } 然后在類A的Clone方法中,newA.myB=myB.Clone(); 比較 1、is運(yùn)算符 檢查對象是否是給定類型或者是否可以轉(zhuǎn)換為給定類型,是則返回true。 如果type是類類型,operand也是該類型,或繼承該類型、封箱到該類型,為true 如果type是接口類型,operand也是該類型,或?qū)崿F(xiàn)該接口的類型,為true 如果type是值類型,operand也是該類型,或拆箱到該類型,為true2、運(yùn)算符重載 public static 返回類型 operator 需重載的運(yùn)算符(參數(shù)??){} 注意不能重載賦值運(yùn)算符,&&和||運(yùn)算符,但可重載&和|;有些運(yùn)算符需成對重載,如“<”和“>” 3、IComparable接口 類A實(shí)現(xiàn)IComparable接口的方法intCompareTo(objectobj)后,利用成員為類A的實(shí)例的ArrayList或Array類可以調(diào)用Sort()方法,按CompareTo(objectobj)的方法排序。 4、IComparer接口 類A實(shí)現(xiàn)IComparer接口的方法intCompare(objectx, objecty)后,利用ArrayList或Array類可以調(diào)用Sort(IA)方法(IComparer IA=new A()),按 Compare(,)方法排序。注意ArrayList或Array類的實(shí)例不一定是類A。也可以在類A中定義一個(gè)公用動(dòng)態(tài)接口成員IComparer ID,這樣可以直接調(diào)用Sort(ID)。另外,在Compare方法中可以調(diào)用Comparer.Default.Compare(,)方法,實(shí)現(xiàn)特定的關(guān)鍵字排序。Default是Compare類的動(dòng)態(tài)實(shí)例。 轉(zhuǎn)換 1、隱式和顯示轉(zhuǎn)換 在沒有繼承關(guān)系,沒有共享接口的類型之間轉(zhuǎn)換時(shí),必須定義類型之間的隱式和顯示轉(zhuǎn)換。public classA {?? //定義A到B的隱式轉(zhuǎn)換 public staticimplicit operatorzhuanB(Aa){?? return } } public classB {?? //定義B到A的顯式轉(zhuǎn)換 public staticexplicit operatorzhuanA(Bb){??return } } 2、as運(yùn)算符 把類型轉(zhuǎn)換為給定類型。 operand類型是type類型,或可以隱式轉(zhuǎn)換為type類型,或封箱到type類型 如果不能轉(zhuǎn)換,則表達(dá)式的結(jié)果是null 異常處理 Exception:所有異常對象的基類。 SystemException:運(yùn)行時(shí)產(chǎn)生的所有錯(cuò)誤的基類。 IndexOutOfRangeException:當(dāng)一個(gè)數(shù)組的下標(biāo)超出范圍時(shí)運(yùn)行時(shí)引發(fā)。NullReferenceException:當(dāng)一個(gè)空對象被引用時(shí)運(yùn)行時(shí)引發(fā)。 InvalidOperationException:當(dāng)對方法的調(diào)用對對象的當(dāng)前狀態(tài)無效時(shí),由某些方法引發(fā)。 ArgumentException:所有參數(shù)異常的基類。 ArgumentNullException:在參數(shù)為空(不允許)的情況下,由方法引發(fā)。ArgumentOutOfRangeException:當(dāng)參數(shù)不在一個(gè)給定范圍之內(nèi)時(shí),由方法引發(fā)。 InteropException:目標(biāo)在或發(fā)生在CLR外面環(huán)境中的異常的基類。ComException:包含COM類的HRESULT信息的異常。 SEHException:封裝Win32結(jié)構(gòu)異常處理信息的異常。 SqlException:封裝了SQL操作異常。 常見具體的異常對象: ArgumentNullException一個(gè)空參數(shù)傳遞給方法,該方法不能接受該參數(shù)ArgumentOutOfRangeException參數(shù)值超出范圍 ArithmeticException出現(xiàn)算術(shù)上溢或者下溢 ArrayTypeMismatchException試圖在數(shù)組中存儲(chǔ)錯(cuò)誤類型的對象 BadImageFormatException圖形的格式錯(cuò)誤 DivideByZeroException除零異常 DllNotFoundException找不到引用的DLL FormatException參數(shù)格式錯(cuò)誤 IndexOutOfRangeException數(shù)組索引超出范圍 InvalidCastException使用無效的類 InvalidOperationException方法的調(diào)用時(shí)間錯(cuò)誤 NotSupportedException調(diào)用的方法在類中沒有實(shí)現(xiàn) NullReferenceException試圖使用一個(gè)未分配的引用OutOfMemoryException內(nèi)存空間不夠 StackOverflowException堆棧溢出 一.讀單音節(jié)字詞 樁 病 款 牌 付 乖 鄭 索 磨 顫 艙 紫 飄 借 笙 衛(wèi) 準(zhǔn) 菌 嘴 頗 約 核 枕 隋 兇 賊 涌 棉 瞬 鍋 釣 買 翁 梗 歐 潤 量 否 砣 笨 缺 來 二.讀詞語(共20分)(限時(shí)3分鐘) 發(fā)揚(yáng) 模型 花蕊 撥拉 配合 旦角兒 快樂 窮忙 調(diào)整 恩情 均勻 喧鬧 森林 拼音 嫂子 車站 一順兒平方 謝謝 稱贊 兩邊 峽谷 志氣 喬裝 蠢蠢 入口 短促 刻苦 刺猬 耐用 瓜分 沸騰 謊言 從而 試卷 拐彎 親愛 手軟 熊貓 總得 具體 脆弱 葬送 落后 需求 拈鬮兒 書架 標(biāo)尺 三.朗讀文章 一個(gè)夏季的下午,我隨著一群小伙伴偷偷上那兒去了。就在我們穿越了一條孤寂的小路后,他們卻把我一個(gè)人留在原地,然后奔向“更危險(xiǎn)的地帶”了,等他們走后,我驚慌失措地發(fā)現(xiàn),再也找不到要回家的那條孤寂的小道了。像只無頭的蒼蠅,我到處亂鉆,衣褲上掛滿了芒刺。太陽已經(jīng)落山,而此時(shí)此刻,家里一定開始吃晚餐了,雙親正盼著我回家??想著想著,我不由得背靠著一棵樹,傷心地嗚嗚大哭起來?? 突然,不遠(yuǎn)處傳來了聲聲柳笛。我像找到了救星,急忙循聲走去。一條小道邊的樹樁上坐著一位吹笛人,手里還正削著什么。走近細(xì)看,他不就是被大家稱為“鄉(xiāng)巴佬兒”的卡廷嗎? 四.命題說話 1.我的愿望 2.學(xué)習(xí)普通話的體驗(yàn) 1.我的愿望 人是要有愿望的,人沒了愿望,就像發(fā)動(dòng)機(jī)沒有了動(dòng)力,人沒愿望,就等于生命缺少了陽光雨露。人在社會(huì)上扮演了多重角色,有著多重的愿望。我是一位青年你,我渴求進(jìn)步;我是一位母親,我期望女兒健康成長;我是一名教師,我希望我的學(xué)生早日成為國家棟梁。我有太多太多的愿望,在這我要說說其中的一個(gè)愿望。就說說教師吧。“師者,傳道受業(yè)解惑也。”師者,既要教書育人,又要教學(xué)相長;既要傳授知識(shí),又要培養(yǎng)能力。要做好教師,可謂責(zé)任重大。自從參加工作做了教師以來,我一直有個(gè)美好的愿望:做一名深受學(xué)生喜歡的良師益友。多年來我一直在努力,但仍然覺得現(xiàn)實(shí)與愿望還有一段差距。要縮短差距,必須做好以下工作:1.熱愛教育,注重情感。教學(xué)是師生雙向的活動(dòng),任何一方未做好,都有可能導(dǎo)致教學(xué)的失敗。一位教育家說,“愛可以彌補(bǔ)天生的缺陷,情可以使寒冷的冬天變得春天般的溫暖。”這充滿哲理的話語,的確可以啟迪許多人的心扉。只要真誠地?zé)釔劢逃P(guān)心學(xué)生,我想對教育的辛勤付出就不會(huì)沒有回報(bào)。2.與時(shí)俱進(jìn),終身學(xué)習(xí)。教師絕不能滿足現(xiàn)狀,要隨時(shí)學(xué)習(xí),及時(shí)調(diào)整知識(shí)結(jié)構(gòu),以免知識(shí)老化。現(xiàn)代是知識(shí)經(jīng)濟(jì)、信息革命的時(shí)代,你若跟不上時(shí)代的步伐,定將是社會(huì)歷史的淘汰者。 3、塑造形象,給人表率。教師的形象,直接或間接地影響著學(xué)生的言行舉止,甚至影響他一生的理想和信念。教師應(yīng)時(shí)時(shí)處處,養(yǎng)成良好的師德規(guī)范,無論是言行舉止,還是衣著打扮,都要體現(xiàn)新時(shí)代教師的精神風(fēng)貌。給學(xué)生和他人留下美好的形象。以上三點(diǎn),若能做好,我想,要做“良師益友”的愿望終會(huì)實(shí)現(xiàn)。2.學(xué)習(xí)普通話的體驗(yàn) 普通話是我國的通用語言,是我們?nèi)粘=涣鳒贤ǖ墓ぞ摺N艺J(rèn)為學(xué)好普通話很重要,尤其是在我們教師的行業(yè)中則更重要。我有這樣一個(gè)體驗(yàn),我本人有許多錯(cuò)誤的讀音,好像我在上學(xué)時(shí)老師就是這樣教的。在我的印象中,上學(xué)時(shí)教我的老師他們以前好像也都讀錯(cuò)了。由此,我現(xiàn)在自己當(dāng)老師了,就別再叫教錯(cuò)自己的學(xué)生了。在普通話學(xué)習(xí)的日子里,我一頭扎進(jìn)書里,早上早起學(xué),下午下班后練。時(shí)間過得很充實(shí),通過學(xué)習(xí),我已經(jīng)矯正了許多自己以前的錯(cuò)誤讀音,同時(shí)也增長了許多自己以前不知道的知識(shí)。比如語氣詞“啊” 的變讀,再比如關(guān)于兒化。要學(xué)好普通話,我覺得有這樣幾條:本人學(xué)習(xí)普通話的體驗(yàn),可簡述以下幾點(diǎn):1.方言音與標(biāo)準(zhǔn)音沖突較大,要有的放矢地學(xué)習(xí)。要多與外地人、陌生人交流交談,養(yǎng)成普通話思維習(xí)慣。2.習(xí)慣發(fā)音與普通話發(fā)音有差距,較難糾正。已成習(xí)慣的,往往自己難于發(fā)現(xiàn),要勇于交談,多交流心得體會(huì),不恥下問。3.普通話學(xué)習(xí)是一個(gè)持續(xù)的過程,不可中斷。如若“兩天打漁你,三天曬網(wǎng)”適合很難學(xué)好的。4.在不斷地聽讀寫看、分析比較的基礎(chǔ)上學(xué)習(xí)。通過學(xué)習(xí)他種方言和外語進(jìn)行比較學(xué)習(xí),也是一種良好的途徑。5.要做生活的有心人,虛心求學(xué),不斷上進(jìn)。只有熱愛生活,取人之長,補(bǔ)己之短,才能學(xué)有所獲。這以上幾點(diǎn)是我學(xué)習(xí)普通話的體驗(yàn)。總之,通過普通話的學(xué)習(xí),使我受益匪淺。第二篇:C#總結(jié)
第三篇:c#讀書筆記
第四篇:C#學(xué)習(xí)心得
第五篇:普通話測試試題