第一篇:c#基礎總結
【1】面向對象程序設計語言的三大特點是什么?答:【23】Main函數特點?答:1)Main方法是C#程序的限定,默認的為private【2】三種命名法則的特點?答:匈牙利命名法:在變限定符,返回類型為void或int類型,Main方法必須是靜態方法;3)一個類或結構只能有一個有效的入駝表示法:一個標示符用若干個有意義的英語單詞或口點函數;4)main方法必須定義在某一個類中。縮寫組成,第一個單詞首字母小寫,后邊的首字母大【24】多態(重寫、隱藏)
寫;Pascal表示法:與駱駝表示法類似,但是第一個 單詞的首字母也需要大寫。【3】C#注釋的三種形式特點?答1)單行注釋:// 2)class A /// {public virtual void F()【4】引用類型和值類型的數據類型? {Console.WriteLine(“A.F”);}} abstract class B:A(1)int valOne = 0;{public abstract override void F();}int valTwo = valOne;答:abstract override 是不可以一起修飾 int valThree = 333;例:在下面的例子里 valTwo = 333;TestValueRefRef1 = new TestValueRef();class A TestValueRefRef2 = Ref1;{public A(){PrintFields();} Ref2.value = 444;public virtual void PrintFields(){} } Console.WriteLine(“values:{0},{1}”, Ref1.value, class B:A Ref2.value);{int x=1;int y;public B(){y=-1;} Console.WriteLine(“values:{0}, {1},{2}”,valOne, public override void valTwo,valThree);PrintFields(){Console.WriteLine(“x={0},y={1}”,答:輸出結果:values:444,444 x,y);} 當使用new B()創建B的實例時,產生什么輸出?(2)public class EnumTest答:x=1,y=0 { enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};分析:執行new B()時,由于B繼承自A,所以會調用static void Main()A的構造函數,并執行其中的PrintFields()方法,由{int x=(int)Days.Sun;inty=(int)Days.Fri;于該方法為虛方法,在繼承類中被重寫,所以,將執Console.WriteLine(“Sun = {0}”, x);行B中的PrintFields()方法。此時,將在DOS界面Console.WriteLine(“Fri = {0}”, y);}} 上輸出“x=1,y=0”,然后,在運行B的構造函數中的答:輸出結果:Sun = 2Fri = 7 y=-1。(建議同學們將此程序放入到代碼中,設置斷點【5】枚舉類型的字段和關聯值?枚舉類型有三個要看執行過程。)
【25】什么是多態對象?答:用基類類名聲明,但是特性 修飾符 enum 枚舉名 : 基礎類型 {枚舉成員聲明,枚舉成員聲明,??,枚舉成員聲明}默認的基礎函數來實例化的對象。這類對象的主要用途是引發多類型為int;關聯值:如果沒有被聲明,默認為0。態,為了將它們和一般的對象(聲明和創建都使用同【6】強制類型轉換(例:若有double f=2.7;int 一個類型名的對象)加以區別、揭示它們的特點和用2)將源類型的對象途,這種形態的對象稱為多態對象。轉換成為目的類型的對象 【26】接口的特點。答:接口只能包含抽象方法,不【7】運算符&和&&的區別?答:條件“與”運算符(&&)沒有訪問修飾符,接口成員必須是方法屬性事件或者時才計算第二個操作數。而&需要計算所有操作數,索引器不能包含常數字段運算符也不能有靜態成員。并且優先級高于&& 【27】委托和事件,【8】裝箱和拆箱的概念?答:裝箱就是把一個值類型委托的定義修飾符 delegate 返回類型 委托類型名(參數列表); 【9】for循環和if語句聯合使用的程序分析,for(;;)eg: public delegate int DelegateClass(stringinfo);
和continue的區別?答:break跳出循委托的創建(實例化)委托對象 = new 委托名(關聯方法); 【11】命名空間的特點答:它提供一種命名機制,是eg: DelegateClass obj=new DelegateClass(MethodA);
合方式無關,不能表明源文件的存取方式,命名空間DelegateClass obj=MethodA;//隱式創建和初是按層次組織的。始化(不用new)【12】數組元素的的復制和讀值 例:分析下列語句: int[3]{5,6,2},new int[5]{6,9,7,8,3},new Hello(string target);} int[2]{3,2}};myArray3[2][2]的值是(D)A)9;B)2;該語句的作用是:在TestCS 命名空間中定義了了一C)6;D)越界 個名為Hello 的委托類型;
【13】類和對象的關系?答:類是對象的抽象,對象【28】Windows窗體中Button按鈕觸發的事件是什【14】關鍵字this和base的區別?答:base指代基【29】Windows窗體中控件的標識符如何修改?答:【15】關鍵字new、using的多種用法?答:new修飾【30】如何修改Windows窗體的啟動窗體?答:修改被重寫,但new修飾符可終止這一特性;向下傳播; 實例化一個對象。Using:導入命名空間;自動釋放【31】要使用SQL Server需要使用哪兩個命名空間? Using代碼框里的資源。【16】索引器的特點?答:索引器允許重載;字符串Using System.Date.SqlClient: 【32】什么是DataSet、DataAdapter?兩者聯系?答:過簽名標識;通過元素訪問來訪問;必須為實例成員;索引器的get訪問器具有與索引器相同的形參表;除DataAdapter:數據適配器,數據庫與DataSet間的橋value參數外,索引器的set訪問器還具有與索引器梁,把數據庫中數據下載到DataSet或回傳回去。相同的形參表。【33】用戶登錄和密碼修改(帶數據庫)【17】靜態數據成員特點?答:為所有類所共享,區用戶登錄 【18】構造函數的特點?答:(1)構造函數名與類名UserName='“ + txtUsername.Text.Trim().ToLower()+ ”' and UserPwd='“ + txtPassword.Text.Trim()+ 【19】析構函數的特點?答:(1)析構函數名是在類”'“;if(OperateDB.ExecuteReader(sql))型(默認為空)和修飾符;(3)析構函數不能被重載。{username = txtUsername.Text.Trim().ToLower();【20】什么是方法的重載?重載的特點是什么?答: frmMain frm = new frmMain();frm.Show();this.Hide();} 定義一組方法。重載的特點:1)位于同一類中;2)else
方法名相同;3)方法參考列表不同,包括參數個數不{MessageBox.Show(”用戶名或密碼錯誤“, ”出錯了“, 同和參數類型不同;4)與方法返回值和修飾符沒關系。MessageBoxButtons.OK, MessageBoxIcon.Error);} 【21】虛函數的特點?答:1)虛方法前不允許有修改密碼: 修飾符;2)虛方法不能是私有的,因此不能使用private修飾符; where UserName='” + frmLogin.username + “' and 【22】抽象類和抽象方法的主要特點?答:抽象類:UserPwd='” + txtOldPwd.Text.Trim()+ “'”;(或者if(OperateDB.ExecuteReader(sqlCheckPwd))說,不能產生對象。但是,它可以有構造函數。(2){string sql = “update UserInfo set UserPwd='” 設計abstract類的目的是為了被繼承。抽象方法:是+ txtNewPwd.Text.Trim()+ “' where UserName='” + 不完整的,不能執行的。frmLogin.username + “'”;
if(OperateDB.ExecuteNonQuery(sql)== 1)
{MessageBox.Show(“密碼修改成功!”);}else
{ MessageBox.Show(“密碼修改失敗!”);}}
else{MessageBox.Show(“舊密碼不正確!”);}
【34】抽象類定義和繼承使用
特點:1.沒有被完整定義,因而它不能用來實例化,或者說,不能產生對象。(但是,它可以有構造函數。)2.設計abstract類的目的是為了被繼承。public abstract class Employee{public virtual void Pay(){ }
public abstract void CalculatePay();} public class HourlyEmployee: Employee
{public override void Pay(){CalculatePay();}public override void CalculatePay(){ }} 【35】接口及繼承類的使用
特定功能的抽象成員的集合。一個類可以繼承多個接口,從而獲得多個行為的描述,將它們組合成新的功能并在類中實現。繼承類中必須實現接口中的所有抽象成員。
定義接口的格式:修飾符 interface 接口名:基接口列表 {接口體} 其中,接口體的聲明可以包括:接口方法聲明;接口屬性聲明;接口事件聲明;接口索引器聲明
public delegate void
StringListEvent(IStringList sender);public interface IStringList{ void Add(string s);//方法int Count{get;}//屬性event StringListEvent Changed;//事件string this[int index]{get;set;}//索引器} 【編程題例題】
定義一MobilePhone類,包括屬性成員——網絡類型(NetworkType),字段成員——屏幕尺寸(screenSize)、手機品牌(brand),手機型號
(brandModel),公共方法成員——Open、Close。其中screenSize為單位是英寸的雙精度數,brand為字符串,NetworkType只能是“GSM”或“CDMA”字符串。要求:(1)在此類中包含構造函數,構造函數用于對數據(屏幕尺寸、手機品牌和手機型號)進行初始化。(2)公共成員方法中輸出相應提示信息(參見(3)中的輸出結果格式)。(3)寫一測試類,在類中實例化一MobilePhone對象,最后能在DOS界面下顯示如下結果:諾基亞N81(屏幕尺寸2.0英寸),是一款GSM手機。手機關機了。using System;
public enum NetworkType {GSM,CDMA,}
public class MobilePhone {public double screenSize;public string brand;
public string brandModel;
public NetworkType networkType;public NetworkType NetworkType{get { return networkType;}}
public MobilePhone(double ss, string bra, string bm, NetworkType nt){screenSize = ss;brand = bra;brandModel = bm;networkType = nt;}public void Open()
{Console.WriteLine(“{0}{1}(屏幕尺寸{2}英寸),是一款{3}手機.”,brand,brandModel,screenSize.ToString(“.0”), networkType);}
public void Close()
{Console.WriteLine(“手機關機了。”);} }
public class Test
{public static void Main()
{MobilePhone mp = new MobilePhone(2.0, “諾基亞”, “N81”, NetworkType.GSM);mp.Open();mp.Close();
System.Console.ReadLine();} }
【例】寫一名為Desk的類,包含兩個字段Length(雙精度類型)、Height(雙精度類型)。再寫一繼承類ComputerDesk類。ComputerDesk類除了有Length和Height外,還有KeyboardTray(字符串類型)。Public class desk {double length;double height;}
Public class computerdesk:desk {string keyboardtray}
第二篇:C#總結
引用類型是類型安全的指針,它們的內存是分配在堆(保存指針地址)上的。String、數組、類、接口和委托都是引用類型。
強制類型轉換與as類型轉換的區別:當類型轉換非法時,強制類型轉換將拋出一System.InvalidCastException異常,而as不會拋出異常,它返回一個null值。用using創建別名:using console = System.Console;訪問限定符:
public 該成員可以被其他任何類訪問 protected 該成員只能被其派生類訪問
private 該成員只能被本類的其他成員訪問 internal 該成員只能在當前編譯單元的其他成員訪問 帶參數列表和返回值的Main方法: class Test {
public static int Main(string[] args)
{
foreach(string arg in args)
{
...}
} } 構造函數(constructor)包括實例構造函數和靜態構造函數。構造函數與類名相同,且不能有返回值。例:
class TestClass {
TestClass()//實例構造函數:可以訪問靜態成員和實例成員,用于初始化實例成員
{
...}
static TestClass()//靜態構造函數:只能訪問靜態成員,用于初始化靜態成員
{
...} } 類的靜態成員屬于類所有,不必生成實例就可以訪問,它是在載入包含類的應用程序時創建的,但靜態方法不能訪問類的實例變量和方法。通常,靜態變量是在定義時就賦初始值的。類的實例成員屬于類的實例所有,不創建實例對象就無法對其進行訪問,實例成員可以訪問類的
靜態成員和其它實例成員。調用基類的析構函數: class A {
public A()
{
...} } class B {
public B(): base()//調用基類的析構函數
{
...} } 常量:其值是在編譯時設定的,必須是數值文字。默認狀態下常量是靜態的。例: class A {
public const double pi = 3.1415;} 常量是編譯時就確定的值,只讀字段是在運行才能確定的值。比如運行時才能確定的屏幕分辨率。
只讀字段只能在類的析構函數中賦值。靜態只讀字段: class A {
public static readonly int ScreenWidth;//靜態只讀字段
static A()
//靜態析構函數
{
ScreenWidth = 1024;//在靜態析構函數中初始化
} } 在類的繼承中,類的析構函數是不會被繼承的。一個派生類只能從一個基類繼承,不能同時從多個基類繼承,但可以通過繼承多個接口來達到相同目的。實現多繼承的唯一方法就是使用接口。例:
class MyFancyGrid: Control, ISerializable, IDataBound {...} 密封類是不能繼承的類,抽象類不能被定義為密封類,且密封類的私有成員不能用protected修飾,只能用private。例: sealed class A {...} 關鍵字ref和out用于指定用引用方式傳遞方法的參數。
它們的區別是:ref參數必須初始化,而out參數不需要初始化。所以在方法處理代碼依賴參數的初始化值時使用ref,不依賴初始化值時使用out。對out參數即使在傳遞前對其進行了初始化,其值也不會傳遞到方法處理函數內部。傳遞時系統會將其設為未初始化。所以在方法內部必須對out參數進行初始化。
方法重載時,必須參數數目和參數類型其中之一不同,返回值不同不能作為重載。C#不支持方法的默認值,只能通過方法重載來實現。例: class A {
int Method(int a)
{
...}
void Method(int a, int b)//參數數目不同
{
//返回值不同不能作為重載
...} } params參數用于一個不定數目參數的方法,一般后面跟一個數組。例: class A {
public void Method(params int[] i)
{
...} } 方法的覆蓋:指派生類覆蓋基類的同名方法,有二種方法
1)第一種是在派生類要覆蓋的方法前面加new修飾,而基類不需要作任何改動。這種方法的缺點是不能實現多態。例: class A {
public void Method()//無需任何修飾
{
...} } class B: A
//從基類繼承
{
new public void Method()//覆蓋基類的同名方法
{
...} } class TestClass {
A Instance = new B();
Instance.Method();//這時將調用類A的Method方法,而不是類B的Method方法 } 2)第二種是在派生類要覆蓋的方法前面加override修飾,而基類的同名方法前面加virtual修飾。這樣就能實現多態,例: class A {
virtual public void Method()
//基類定義虛方法
{
//虛擬方法不能定義為private,因為private成員對派生類是無法訪問的...} }
class B: A
//從基類繼承 {
override public void Method()
//派生類覆蓋基類的同名虛方法
{
...} } class TestClass {
protected void Test()
{
A Instance = new B();
//定義一個實例,類型為基類,從派生類創建
//派生類總是能夠向上轉換為其基類
Instance.Method();
//將調用派生類B的Method方法,而不是基類的,這就是多態
} } 說明:new修飾的方法覆蓋不能實現多態的原因,是因為使用new時編譯器只會實現早期綁定(early binding)。即調用的方法在編譯時就決定了:編譯器看到Instance.Method()而Instance的類是A,就會調用類A的Method()方法。
override修飾的方法覆蓋可以實現多態的原因,是因為實現了后期綁定(late binding)。使用override時強制編譯器在運行時根據類的真正類型正確調用相應的方法,而不是在編譯時。
而基類的同名方法必須加virtual修飾。
類的靜態方法可能通過 類名.靜態方法名 這種格式來調用,不能使用 實例名.靜態方法名 這種方法調用。
因為類的靜態方法為類所有(是屬于類本身的),而非實例所有(不是屬于類的實例的)。類的靜態方法可以訪問類的任何靜態成員,但不能訪問類的實例成員。C#中類的變量稱為字段。類的public變量稱為類的公共字段。
類的屬性由一個protected(也可以是private)字段和getter和setter方法構成: class Address {
protected string zipCode;//protected字段,注意大小寫
public string ZipCode
{
get
//getter方法
{
return zipCode;
}
set
//setter方法
{
zipCode = value;//被傳遞的值自動被在這個value變量中
}
};} 只讀屬性是指省略setter方法的屬性,只讀屬性只能讀取,不能設置。
屬性也可以用限定符virtual,override和abstract修飾,功能同其他類的方法。
屬性有一個用處稱為懶惰的初始化(lazy initialization)。即在需要類成員時才對它們進行初始化。如果類中包含了很少被引用的成員,而這些成員的初始化又會花費大量的時候和系統資源的話,懶惰的初始化就很有用了。C#中數組對象共同的基類是System.Array。將數組聲明為類的一個成員時,聲明數組與實例化數組必須分開,這是因為只能在運行時創建了類的實例對象之后,才能實例化數組元素值。聲明:
int[] intArray;//一維數組 int[,] int3Array;//三維數組 初始化:
intArray = new int[3] {1,2,3};int[,] int2Array = new int[2,3] {{1,2,3},{4,5,6}};//聲明時可以初始化 遍歷:
1)一維數組
for(int i = 0;i < intArray.Length;i++);//Array.Length返回數組所有元素的個數 foreach(int i in intArray);for(int i = 0;i < intArray.GetLength(0);i++);//Array.GetLength(0)返回數組第一維的個數 2)多維數組
for(int i = 0;i < int3Array.GetLength(0);i++)//遍歷三維數組
for(int j = 0;j < int3Array.GetLength(1);j++)
for(int k = 0;k < int3Array.GetLength(2);k++)
{
...} 數組的維數就是該數組的秩(Rank)。Array.Rank可以返回數據的秩。鋸齒數組(jagged Array)是元素為數組的數組,例:
int[][] jaggedArray = new int[2][];//包含二個元素,每個元素是個數組 jaggedArray[0] = new int[2];//每個元素必須初始化 jaggedArray[1] = new int[3];for(int i = 0;i < jaggedArray.Length;i++)//遍歷鋸齒數組
for(int j = 0;j < jaggedArray[i].Length;j++)
{
...} 類的屬性稱為智能字段,類的索引器稱為智能數組。由于類本身作數組使用,所以用this作索引器的名稱,索引器有索引參數值。例: using System;using System.Collections;class MyListBox {
protected ArrayList data = new ArrayList();
public object this[int idx] //this作索引器名稱,idx是索引參數
{
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
{
//拋出一個異常
}
}
} } 接口是二段不同代碼之間約定,通過約定實現彼此之間的相互訪問。C#并不支持多繼承,但通過接口可實現相同功能。當在接口中指定了實現這個接口的類時,我們就稱這個類“實現了該接口”或“從接口繼承”。一個接口基本上就是一個抽象類,這個抽象類中除了聲明C#類的其他成員類型——例如屬性、事件和索引器之外,只聲明了純虛擬方法。接口中可以包含方法、屬性、索引器和事件——其中任何一種都不是在接口自身中來實現的。例:
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;} } 說明:定義接口時,在方法、屬性、事件和索引器所有這些接口成員都不能用public之類的訪問限定符,因為所有接口成員都是public類型的。因為接口定義了一個約定,任何實現一個接口的類都必須定義那個接口中每一個成員,否則將編譯失敗。例: 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()//實現接口
{
if(data == “my control data”)
return true;
else
return false;
} } class InterfaceApp {
MyControl myControl = new MyControl();
IValidate val =(IValidate)myControl;//可以將一個實現某接口的類,轉換成該接口
bool success = val.Validate();//然后可調用該接口的方法 } 也可以用:bool success = myControl.Validate();這種方法來調用Validate方法,因為Validate在類MyControl中是被定義成public的,如果去除public,Validate方法被隱藏,就不能用這種方法調用了,這樣隱藏接口方法稱為名字隱藏(name hiding)。可以用:類實例 is 接口名 來判斷某個類是否實現了某接口,例: myControl is IValidate //MyControl類的實例myControl是否實現了IValidate接口
當然,也可用as來作轉換,根據轉換結果是否為null來判斷某個類是否實現了某接口,例: IValidate val = myControl as IValidate;if(null == val){...//沒有實現IValidate接口 } else {...//實現了IValidate接口
}
如果一個類從多個接口繼承,而這些接口中如果定義的同名的方法,則實現接口的方法時,必須加接口名來區別,寫成 接口名.方法名。假設Test類從IDataStore和ISerializable二個接口繼承,而這二個接口都有SaveData()方法,實現SaveData()方法時必須寫成: class Test: ISerializable, IDataStore {
void ISerializable.SaveData()
{
...}
void IDataStore.SaveData()
{
...} } 如果一個類從多個接口繼承,為了方便可以定義一個新的接口,這個接口繼續多個接口,然后類直接從這個接口繼承就可以了,這個叫合并接口。例: interface ISaveData: ISerializable, IDataStore { //不需要定義任何方法或成員,只是用作合并 } class Test: ISaveData //只要繼承ISaveData就可以了 {...} C# 操作符優先級(從高到低)
初級操作符()x.y f(x)a[x] x++ x--new typeof sizeof checked unchecked 一元操作符 +位移操作符 << >> 關系操作符 < > <= >= is 等于操作符 == 邏輯與
& 邏輯異或 ^ 邏輯或
| 條件與
&& 條件或
|| 條件操作符 ?: 賦值操作符 = *= /= %= +=-= <<= >>= &= ^= |= 所有的二元操作符除賦值符外都是左聯合的,即從左到右計算。
typeof()運算符可以從一個類名得到一個System.Type對象,而從System.Object對象繼承來的GetType()方法則可從一個類實例來得到一個System.Type對象。例: Type t1 = typeof(Apple);//Apple是一個類名
Apple apple = new Apple();//apple是Apple類的一個實例 Type t2 = apple.GetType();//t1與t2是相同的 通過反射得到一個類的所有成員和方法: 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()操作符用來計算值類型變量在內存中占用的字節數(Bytes),并且它只能在unsafe(非安全)
代碼中使用。例:
static unsafe public void ShowSizes(){
int i, j;
j = sizeof(short);
j = sizeof(i);} 盡可能使用復合賦值操作符,它比不用復合賦值操作符的效率高。for語句的語法為:
for(initialization;Boolean-expression;step)
embedded-statement 在initialization和step部份還可以使用逗號操作符,例: 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++中的函數指針相同,代表不是在編譯時被定義的,而是在運行時被定義的。
代表主要有二個用途:回調(Callback)和事件處理(event)回調通常用于異步處理和自定義處理。例: class DBManager {
static DBConnection[] activeConnections;
//聲明回調函數
public void delegate EnumConnectionCallback(DBConnection connection);
public static void EnumConnections(EnumConnectionCallback callback)
{
foreach(DBConnection connection in activeConnections)
{
callback(connection);//執行回調函數
}
} } //調用
class DelegateApp {
public static void ActiveConncetionCallback(DBConnection connection)//處理函數
{
...}
public void main()
{
//創建指向具體處理函數的代表實例(新建一個代表,讓它指向具體的處理函數)
DBManager.EmnuConnectionCallback myCallback = new DBManager.EmnuConnectionCallback(ActiveConncetionCallback);
DBManager.EnumConnections(myCallback);
} } //使用靜態代表,上面的調用改為 class DelegateApp {
//創建一個指向處理函數的靜態代表
public static DBManager.EmnuConnectionCallback myCallback
= new DBManager.EmnuConnectionCallback(ActiveConncetionCallback);
public static void ActiveConncetionCallback(DBConnection connection)
{...} public void main()
{
DBManager.EnumConnections(myCallback);
} } //在需要時才創建代表,上面的調用改為
class DelegateApp {
//將創建代表放在屬性的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();//創建應用程序
DBManager.EnumConnections(myCallback);
} } 可以將多個代表整合成單個代表,例: class CompositeDelegateApp {
public static void LogEvent(Part part)
{
...}
public static void EmailPurchasingMgr(Part part)
{
...}
public static void Main()
{
//定義二個代表
InventoryManager.OutOfStockExceptionMethod LogEventCallback
= new InventoryManager.OutOfStockExceptionMethod(LogEvent);
InventoryManager.OutOfStockExceptionMethod EmailPurchasingMgrCallback
= new InventoryManager.OutOfStockExceptionMethod(EmailPurchasingMgr);
//整合為一個代表,注意后加的代表先執行(這里是先執行LogEventCallback)
InventoryManager.OutOfStockExceptionMethod onHandExceptionEventsCallback
= EmailPurchasingMgrCallback + LogEventCallback;
//調用代表
InventoryManager mgr = new InventoryManager();
mgr.ProcessInventory(onHandExceptionEventsCallback);
//InventoryManager類的ProcessInventory方法的原型為:
//public void ProcessInventory(OutOfStockExceptionMethod exception);
} } 可以根據需要將多個代表自由地組合成單個代表,例: class CompositeDelegateApp {
//代表指向的處理函數(三個代表三個函數)
public static void LogEvent(Part part)
{
...} public static void EmailPurchasingMgr(Part part){...}
public static void EmailStoreMgr(Part part)
{
...}
public static void Main()
{
//通過數組定義三個代表
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;
//再定義一個代表(用于組合成單代表)
InventoryManager.OutOfStockExceptionMethod compositeDelegate;
//根據需要組合
if(location = 2)
{
compositeDelegate = exceptionMethods[0] + exceptionMethods[1];
}
else
{
compositeDelegate = exceptionMethods[0] + exceptionMethods[2];
}
//調用代表
InventoryManager mgr = new InventoryManager();
mgr.ProcessInventory(compositeDelegate);
} } C#的事件遵循“發布——預訂”的設計模式。在這種模式中,一個類公布能夠出現的所有事件,然后任何的類都可以預訂這些事件。一旦事件產生,運行環境就負責通知每個訂戶事件已經發生了。
當代表作為事件的處理結果時(或者說定義具有代表的事件),定義的代表必須指向二個參數的方法:一個參數是引發事件的對象(發布者),另一個是事件信息對象(這個對象必須從EventArgs類中派生)。例: using System;
class InventoryChangeEventArgs: EventArgs //事件信息對象,從EventArgs類派生 {...//假設定義二個public屬性string Sku和int Change } class InventoryManager
//事件的發布者 {
//聲明代表
public delegate void InventoryChangeEventHander(object source, InventoryChangeEventArgs e);
//發布事件,event關鍵字可將一個代表指向多個處理函數
public event InventoryChangeEventHandler onInventoryChangeHander;
public void UpdateInventory(string sku, int change)
{
if(change == 0)
return;
InventoryChangeEventArgs e = new InventoryChangeEventArgs(sku, change);
//觸發事件
if(onInventoryChangeHandler!= null)//如果有預訂者就觸發
onInventoryChangeHandler(this, e);//執行代表指向的處理函數
} } class InventoryWatcher
//事件的預訂者 {
public InventoryWatcher(InventoryManager mgr)//mgr參數用于聯結發布者
{
this.inventoryManager = mgr;
//預訂事件,用 += 調用多個處理函數
mgr.onInventroyChangeHandler += new InventoryManager.InventoryChangeEventHandler(onInventoryChange);
//事件處理函數
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等操作系統都支持占先型多任務。在占先型多任務執行中,處理器負責
給每個線程分配一定量的運行時間——一個時間片(timeslice)。處理器接著在不同的線程之間進行切換,執行相應的處理。在單處理器的計算機上,并不能真正實現多個線程的同時運行,除非運行在多個處理器 的計算機上。操作系統調度的多線程只是根據分配給每個線程時間片進行切換執行,感覺上就像同時執行。
上下文切換(context switching)是線程運行的一部分,處理器使用一個硬件時間來判斷一個指定線程的時間片何時結束。當這個硬件計時器給出中斷信號時,處理器把當前運行的線程所用的所有寄存器(registers)數據存儲到堆棧中。然后,處理器把堆棧里那些相同的寄存器信息存放到一種被稱為“上下文結構”的數據結構中。當處理器要切換回原來執行的線程時,它反向執行這個過程,利用與該線程相關的上下文結構,在寄存器里重新恢復與這一線程相關的信息。這樣的一個完整過程稱為“上下文切換”。多線程允許應用程序把任務分割為多個線程,它們彼此之間可以獨立地工作,最大限度地利用了處理器時間。using System;using System.Threading;class SimpleThreadApp {
public static void WorkerThreadMethod()//線程的執行體
{
...//執行一些操作
}
public static void Main()
{
//創建一個線程代表指向線程的執行體,ThreadStart是創建新線程必須用到的代表
ThreadStart worker = new ThreadStart(WorkerThreadMethod);
Thread t = new Thread(worker);//用線程代表創建線程
t.Start();
//執行線程
} } 可以通過兩種方式來得到一個Thread對象:一種是通過創建一個新線程來得到,如上例;另一種在正在執行的線程調用靜態的Thread.CurrentThread方法。
靜態方法Thread.Sleep(int ms)可以讓當前線程(它自動調用Thread.CurrentThread)暫停指定毫秒的時間。
如果使用Thread.Sleep(0)那么當前線程將一直處于等待中,直到另一個線程調用這個線程的實例方法Thread.Interrupt方法,等待才會結束。使用Thread.Suspend方法也能掛起線程,Thread.Suspend方法可以被當前線程或其他線程調用,而Thread.Sleep(0)只能由當前線程在執行體中調用。當線程用Thread.Suspend掛起時,必須用Thread.Resume方法恢復。不論Thread.Suspend方法調用了多少次,只要調用Thread.Resume方法一次就可以線程恢復執行。用Thread.Suspend方法并不會阻塞線程,調用立即返回。而Thread.Sleep(0)則會阻塞線程。所以確切地說Thread.Sleep(0)暫停線程,而不是掛起線程。
使用Thread.Abort方法可以終止正在執行的線程。當Thread.Abort方法被調用時,線程不會立即終止執行。運行環境將會等待,直到線程到達文檔中所描述的“安全點”。如果要確保線程已經完全停止,可以使用Thread.Join方法。這是一個同步調用,同步調用意味著直到線程完全停止,調用才會返回。
Thread.Priority屬性用于設置的線程的優先級。其值是Thread.ThreadPriority枚舉值,可以設為Highest, AboveNormal,Normal, BelowNormal, Lowest。缺省值是Thread.ThreadPriority.Normal。
線程的同步是為了解決多個線程同時使用同一對象產生的一些問題。通過同步,可以指定代碼的臨界區(critical section),一次只有一個線程可以進入臨界區。使用System.Monitor類(鎖定與信號量)進行線程同步: using System;using System.Threading;public void SaveData(string text)//線程執行函數或線程執行函數調用的對象的方法 {
...//執行其他一些不需要同步的處理
Monitor.Enter(this);//獲取對象的Monitor鎖
...//執行需要同步的處理
Monitor.Exit(this);//釋放對象的Monitor鎖
...//執行其他一些不需要同步的處理
} 說明:當執行Monitor.Enter方法時。這個方法會試圖獲取對象上的Monitor鎖,如果另一個線程已經擁有了這個鎖,這個方法將會阻塞(block),直到這個鎖被釋放。
也可用C#的lock語句來獲得和釋放一個Monitor鎖。上面同步寫成:public void SaveData(string text)//線程執行函數或線程執行函數調用的對象的方法 {
...//執行其他一些不需要同步的處理
lock(this)//獲取對象的Monitor鎖,代碼塊執行完成后釋放Monitor鎖
{
...//執行需要同步的處理
}
...//執行其他一些不需要同步的處理 } 也可以使用System.Threading名稱空間的Mutex類(互斥類)進行線程同步。與Monitor鎖一樣,一次只有一個線程能獲得一個給定的互斥。但Mutex要慢得多,但它增加了靈活性。例:
using System;using System.Threading;class Database {
Mutex mutex = new Mutex(false);//創建一個互斥,但不立即獲得它
//注意:創建互斥在需要同步的方法之外,實際上它只要創建一個實例
public void SaveData(string text)//需要同步的方法
{
mutex.WaitOne();//等待獲得互斥
...//需要同步的處理
mntex.Close();//釋放互斥
} } Mutex類重載了三個構造函數:
Mutex()
//創建并使創建類立即獲得互斥
Mutex(bool initiallyOwned)
//創建時可指定是否要立即獲得互斥 Mutex(bool initiallyOwned, string muterName)//還可以指定互斥的名稱 Mutex.WaitOne方法也重載了三次: Mutex.WaitOne()
//一直等待
Mutex.WaitOne(TimeSpan time, bool exitContext)//等待TimeSpan指定的時間 Mutex.WaitOne(int milliseconds, bool exitContext)//等待指定的毫秒 線程的用法:
1)并發操作:比如一個程序監視多個COM口,當每個COM接到信息時執行一段處理時。2)復雜長時間操作:一個長時間的復雜操作可能會使界面停滯,停止用戶響應,如果還允許用戶停止它,或者顯示進度條、顯示操作執行進程信息時。
反射(Reflection)就是能夠在運行時查找類型信息,這是因為.NET編譯的可執行(PE)文件中包括MSIL和元數據(metadata)。
反射的中心是類System.Type。System.Type是一個抽象類,代表公用類型系統(Common Type System, CTS)中的一種類型。
using System;using System.Reflection;//反射命名空間,必須引用 public static void Main(string[] args){
int i = 6;
Type t = i.GetType();
//根據實例得到類型
t = Type.GetType(“System.Int32”);//根據類型的字符名稱得到類型
} 通過Assembly類可以得到已經編譯.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)//如果參數為空,取當前進程的名稱
{
Process p = Process.GetCurrentProcess();
assemblyName = p.ProcessName + “.exe”;
}
else
assemblyName = args[0];//取第一個參數,即當前運行程序名
return assemblyName;
}
public static void Main(string[] args)
{
string assemblyName = GetAssemblyName(args);
Assembly a = Assembly.LoadFrom(assemblyName);//調用編譯程序集
Type[] types = a.GetTypes();
//得到多個類型
foreach(Type t in types)
//遍歷類型數組
{
...//取得t.FullName,t.BaseType.FullName等類型信息
}
} } 一個應用程序可以包括多個代碼模塊。若要將一個cs文件編譯一個模塊,只要執行下面的命令:
csc /target:module 要編譯的模塊.cs //csc是C Sharp Compiler(C#編譯器)然后在應用程序中using編譯的模塊.cs中的NameSpace即可應用了。要反射應用程序中所有代碼模塊(Module),只要:
Assembly a = Assembly.LoadFrom(assemblyName);//應用程序的物理文件名 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);//生成實例
MethodInfo mi = t.GetMethod(“DisplayName”);
mi.Invoke(o, null);
//調用方法
}
} } //帶參數的例子
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);
// 定義參數類型
Type[] paramTypes = new Type[1];
paramTypes[0]= Type.GetType(“System.Double”);
MethodInfo CosineInfo = t.GetMethod(“Cos”, paramTypes);
//設置參數數據
Object[] parameters = new Object[1];
parameters[0] = 45;
//執行方法
Object returnVal = CosineInfo.Invoke(o, parameters);
Console.WriteLine(“The cosine of a 45 degree angle {0}”, returnVal);
}
} } 動態生成代碼和動態調用的完整例子: //動態生成代碼的部分 using System;using System.Reflection;using System.Reflection.Emit;//動態生成代碼必須引用 namespace ILGenServer {
public class CodeGenerator
{
public CodeGenerator()
{
currentDomain = AppDomain.CurrentDomain;//得到當前域
assemblyName = new AssemblyName();//從域創建一個程序集
assemblyName.Name = “TempAssembly”;
//得到一個動態編譯生成器,AssemblyBuilerAccess.Run表示只在內存中運行,不能保存
assemblyBuilder = currentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilerAccess.Run);
//從編譯生成器得到一個模塊生成器
moduleBuilder = assemblyBuilder.DefineDynamicModule(“TempModule”);
//模塊生成器得到類生成器
typeBuilder = moduleBuilder.DefineType(“TempClass”, TypeAttributes.Public);
//為類添加一個方法
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;
}
}
} } //動態調用的部分
using System;using System.Reflection;using ILGenServer;//引用動態生成代碼的類 public class ILGenClientApp {
public static void Main({
CodeGenerator gen = new CodeGenerator();//創建動態生成類
Type t = gen.T;
if(null!= t)
{
object o = Activator.CreateInstance(t);
MethodInfo helloWorld = t.GetMethod(“HelloWorld”);//為調用方法創建一個MethodInfo
if(null!= helloWorld)
{
helloWorld.Invoke(o, null);//調用方法
}
}
} } 調用DLL using System;using System.Runtime.InteropServices;//為了使用DLLImport特性
class PInvokeApp {
[DllImport(“user32.dll”, CharSet=CharSet.Ansi)] //CharSet.Ansi指定Ansi版本的函數(MessageBoxA),CharSet.Unicode指定Unicode版本的函數(MessageBoxW)
static extern int MessageBox(int hWnd, string msg, string caption, int type);//聲明DLL中的函數
//[DllImport(“user32.dll”, EntryPoint=“MessageBoxA”)] //用這種方法使用不同的函數名
//static extern int MsgBox(int hWnd, string msg, string caption, int type);
//[DllImport(“user32.dll”, CharSet=CharSet.Unicode)] //調用Unicode版的DLL函數
//static extern int MessageBox(int hWnd, [MarshalAs(UnmanagedType.LPWStr)]string msg,// [MarshalAs(UnmanagedType.LPWStr)]string caption, int type);//將LPWStr翻譯為string型,缺省情況系統只將LPStr翻譯成string
public static void Main()
{
MessageBox(0, “Hello, World!”, “CaptionString”, 0);//調用DLL中的函數
} } 例2,使用回調: 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);
} } 關鍵字unsafe指定標記塊在非控環境中運行。該關鍵字可以用于所有的方法,包括構造函數和屬性,甚至還有方法中的代碼塊。關鍵字fixed負責受控對象的固定(pinning)。Pinning是一種動作,向垃圾收集(Garbage Collector, GC)指定一些不能被移動的對象。為了不在內存中產生碎片,.NET運行環境把對象四處移動,以便于最有效地利用內存。使用fixed后指定對象將不會被移動,所以就可以用指針來訪問它。
C#中只能得到值類型、數組和字符串的指針。在數組的情況下,第一個元素必須是值類型,因為C#實際上是返回一個指向數組第一個元素的指針,而不是返回數組自身。& 取一個變量的內存地址(即指向該變量的指針)* 取指針所指變量的值-> 取成員
例: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是任何產生一個type指針的表達式;statements是應用的代碼塊。例: fixed(int* f = &foo.x)//foo是Foo類的一個實例,x是Foo類的一個int屬性 {
SetFooValue(f);//SetFooValue方法的定義為unsafe static void SetFooValue(int* x)} 傳統的COM組件可以通過互操作層(COM Interop)與.NET運行環境交互。互操作層處理在托管運行環境和非托管區域中的COM組件操作之間傳遞所有的消息。
要使COM組件能在.NET環境中使用,必須為COM組件生成元數據。.NET運行環境用元數據層業判斷類型信息。在運行時刻使用類型信息,以便生成RCW(Runtime Callable Wrapper,運行時可調用包裝)。當.NET應用程序與COM對象交互時,RCW處理對COM對象的裝載和調用。RCW還完成許多其他的工作,如管理對象標識、對象生存周期以及接口緩沖區。對象生存周期管理十分關鍵,因為.NET GC把對象到處移動,并且當對象不再使用時,自動處理這些對象。RCW服務告訴.NET,應用程序正與托管.NET組件交互,同時又使非托管COM組件“覺得”COM對象是被傳統的COM客戶端調用的。
為了為COM組件生成元數據包裝,必須使用tlbimp.exe(TypeLib Importer)工具: tlbimp some_COM.tlb /out:som_COM.dll
第三篇:C#基礎編程設計實驗報告
C# 基礎編程 設計實驗報告
一、實驗目的
1、熟悉 Visual Studio.NET 開發環境。
2、掌握 C#應用程序的基本操作過程。
3、掌握 C#的數據類型,運算符以及表達式的使用。
4、掌握分支和循環語句的使用方法。
5、掌握一維數組,二維數組及數組型數組的使用。
二、實驗要求
(1)編寫程序要規范、正確,上機調試過程和結果要有記錄(2)做完實驗后給出本實驗的實驗報告。
三、實驗設備、環境
安裝有 Visual Studio.NET 軟件。
四、實驗步驟
1、分析題意。
2、根據題目要求,新建項目。
3、編寫并輸入相關的程序代碼。
5、運行與調試項目。
6、保存項目。
五、實驗內容
1、編寫一個簡單的控制臺應用程序,打印一行文字(如你的姓名)。
using System;using System.Collections.Generic;
using System.Linq;using System.Text;
namespace one.first {
class Program
{
static void Main(string[] args)
{
System.Console.WriteLine(“我叫王蕾!”);
}
} } 2、編寫一個簡單的 Windows 應用程序,在窗體 Load 事件中書寫代碼,標簽中顯示你的姓名。
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;
using System.Windows.Forms;
namespace one.second {
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.Text = “Windows 程序”;
Label lblShow = new Label();
lblShow.Location = new Point(20, 30);
lblShow.AutoSize = true;
lblShow.Text = “王蕾!”;
this.Controls.Add(lblShow);
}
}
} 3、編寫一個一個程序,用來判斷輸入的是大寫字母,小寫字母,數字還是其他的字符。
using System;using System.Collections.Generic;using System.Text;
namespace one.third {
class Program
{
static void Main(string[] args)
{
Console.WriteLine(“請輸入一個字符:”);
char c = Convert.ToChar(Console.ReadLine());
if((c>=“a”&&c<=“z”)||(c>=“A”&&c<=“Z”))
Console.WriteLine(“這是一個字母”);
if(char.IsDigit(c))
Console.WriteLine(“這是一個數字”);
}
}
} 4、分別用 while,do-while,for 循環求 1 到 100 的和。
using System;using System.Collections.Generic;using System.Text;
namespace one.forth.one {
class Program
{
static void Main(string[] args)
{
int i = 1, sum = 0;
while(i <= 100)
{
sum = sum + i;
i++;
}
Console.WriteLine(“1 到 100 的自然數之和為:” + sum);
}
}
} using System;using System.Collections.Generic;using System.Text;
namespace one.forth.two {
class Program
{
static void Main(string[] args)
{
int i = 1, sum = 0;
do
{
sum = sum + i;
i++;
}
while(i <= 100);
Console.WriteLine(“1 到 100 的自然數的和為:” + sum);
}
}
} using System;using System.Collections.Generic;using System.Text;
namespace one.forth.three {
class Program
{
static void Main(string[] args)
{
int i , sum = 0;
for(i = 1;i <= 100;i++)
{
sum = sum + i;
}
Console.WriteLine(“1 到 100 的自然數的和為:” + sum);
}
} } 5、定義一個一維數組,用隨機數為此賦值,用 foreach 循環輸
出其中的內容。
using System;using System.Collections.Generic;using System.Linq;using System.Text;
namespace first.five {
class Program
{
static void Main(string[] args)
{
int[] a = {0,1,2,3,4};
foreach(int i in a)
{
Console.WriteLine(a[i]);
}
}
} } 6、實現二維數組的輸入和輸出。
using System;
using System.Collections.Generic;using System.Linq;using System.Text;
namespace first.six {
class Program
{
static void Main(string[] args)
{
int[,] a = new int[2, 3] { { 1, 2, 3 }, { 4, 5, 6 } };
{
for(int i = 0;i < 2;i++)
{
for(int j = 0;j < 3;j++)
{ Console.WriteLine(a[i, j]);}
}
}
}
} }
7、實現數組型數組的輸入和輸出。
using System;using System.Collections.Generic;using System.Linq;using System.Text;
namespace first.seven {
class Program
{
static void Main(string[] args)
{
int[][] a = new int[][] { new int[] { 1, 2, 3 }, new int[] { 4, 5, 6 } };
for(int i = 0;i < a.Length;i++)
{
for(int j = 0;j < a[i].Length;j++)
{
Console.WriteLine(a[i][j]);
}
}
}
} } 六、實驗體會(遇到問題及解決辦法,編程后的心得體會)
剛開始編程的時候覺得無從下手,盡管我們已經學了好幾種高級編程語言,但每個都有其獨特的地方,稍不留神就會混淆。
通過這次實驗,我體會到課后復習鞏固的重要性。在編程的時候,很多內容都不記得,需要去翻書。不得不說,實驗是鞏固課程的好方法!本次實驗,我熟悉 Visual Studio.NET 開發環境;掌握了 C#應用程序的基本操作過程;掌握了 C#的數據類型,運算符以及表達式的使用;掌握了分支和循環語句的使用方法以及一維數組,二維數組及數組型數組的使用。
實驗項目名稱:
類與對象
實驗學時:
同組學生姓名:
實驗地點:
1318
實驗日期:
月 26 日-11 月 9 日 實驗成績:
批改教師:
批改時間:
實驗 2
類與對象
一、實驗目的、要求
(1)掌握類的定義和使用;(2)掌握類的數據成員,屬性的定義和使用;(3)掌握方法的定義,調用和重載以及方法參數的傳遞;(4)掌握構造函數的定義和使用。
二、實驗要求
(1)編寫程序要規范、正確,上機調試過程和結果要有記錄;(2)做完實驗后給出本實驗的實驗報告。
三、實驗設備、環境
安裝有 Visual Studio.NET 軟件。
四、實驗步驟
1、分析題意; 2、根據題目要求,新建項目; 3、編寫并輸入相關的程序代碼; 5、運行與調試項目; 6、保存項目。
五、實驗內容
1、定義一個方法,實現兩個數的交換(分別把參數按值傳遞和按引用傳遞)。
using System;
using System.Collections.Generic;using System.Text;
namespace second.one {
class Program
{
static void Main(string[] args)
{
Swaper s = new Swaper();
Console.WriteLine(“輸入 x 的值:”);
int a = Convert.ToInt32(Console.ReadLine());
Console.WriteLine(“輸入 y 的值:”);
int b=Convert.ToInt32(Console.ReadLine());
Console.WriteLine(s.Swap(a, b));
Console.WriteLine(s.Swap(ref a,ref b));
}
class Swaper
{
public string Swap(int x, int y)
{
int temp;
temp = x;
x = y;
y = temp;
return string.Format(“按值傳參交換之后:x={0},y={1}”,x,y);
}
public string Swap(ref int x, ref int y)
{
int temp;
temp = x;
x = y;
y = temp;
return string.Format(“按引用傳參交換之后:x={0},y={1}”, x, y);
}
}
} }2、定義一個方法,實現數組的排序。
using System;using System.Collections.Generic;using System.Text;
namespace second.two {
class Program
{
public class sort
{
public void change(int[] a)
{
Console.WriteLine(“排序前,數組順序為:”);
show(a);
int i, j, m;
for(i = 0;i < 10;i++)
{
m = a[i];
j = i-1;//a[j]為數組前一個值
while(j >= 0 && m > a[j])//判斷 i 下標的數是否大于 j 下標的數
{
a[j + 1] = a[j];//如果 i 下標大于j 把 j 往后移一個位
j--;
}
a[j+1] = m;//當不大于 j 的時候就把 M的值放到 i 下標下面 j+1 是為了下標減到最前時考慮-1 + 1 還是下標的最前面
}
Console.WriteLine(“排序后,數組順序為:”);
show(a);
}
void show(int[] a)
{
int i;
for(i = 0;i < 10;i++)
{
Console.Write(“{0} ”, a[i]);
}
Console.WriteLine();
}
}
static void Main(string[] args)
{
int[] a ={ 4, 7, 1, 2, 5, 8, 9, 10, 3, 6 };
sort s=new sort();
s.change(a);
}
} } 3、定義一個學生類,把學生類當作對象來傳遞。
using System;using System.Collections.Generic;using System.Linq;using System.Text;
namespace second.three {
class Program
{
public class student
{
public void st()
{
int a = 999;
}
}
public class st
{
public void aa(student s)
{
Console.WriteLine(s);
}
}
static void Main(string[] args)
{
student s=new student();
st s1 = new st();
s1.aa(s);
}
} } 4、定義一個方法,求兩個數的和和差,通過參數把這兩個值帶回。
using System;using System.Collections.Generic;using System.Linq;using System.Text;
namespace
second.four
{
class Program
{
public class sum
{
public void ab(out int m, out
int n,int a, int b)
{
m = a + b;
n = a-b;
}
}
static void Main(string[] args)
{
sum s = new sum();
int a = 10;
int b = 3;
int m, n;
s.ab(out m, out n, a, b);
Console.WriteLine(“{0}+{1}={2};{0}-
{1}={3}”,a,b,m,n);
}
} } 5、用構造函數重載,實現矩形的面積,圓的面積,梯形的面積; using System;using System.Collections.Generic;using System.Linq;using System.Text;
namespace secong.five {
class Program
{
public class square
{
public double area;
public square(){ }
public square(double a)
{
area = a * a * 3.14;
}
public square(double a, double b)
{
area = a * b;
}
public square(double a, double b, double h)
{
area =(a + b)/ 2 * h;
}
}
static void Main(string[] args)
{
double a, b, h,area;
a = 2;b = 5;h = 3;
square s = new square(a,b);
Console.WriteLine(“求矩形面積,長為 a={0},寬為 b={1},面積 area={2}”,a,b,s.area);
square i = new square(a);
Console.WriteLine(“求圓形面積,半徑 a={0},面積 area={1}”, a, i.area);
square j = new square(a, b, h);
Console.WriteLine(“求梯形面積,上底為a={0},下底為 b={1},高為 h={2}面積 area={3}”, a, b,h, j.area);
}
} } 6、設計一個 windows 應用程序,在該程序中定義一個學生類和班級類,以處理每個學生的學號,姓名,語文,數學和英語成績,要求:
1)能查詢每個學生的總成績。
2)能顯示全班前三名的名單。
3)能顯示單科成績最高分和不及格的學生名單。
4)能統計全班學生的平均成績。
5)能顯示各科成績不同分數段的學生人數的百分比。
Student 類:
using System;using System.Collections.Generic;using System.Text;namespace Test2_6 {
public class Student
{
public string stuNo;
public string name;
public double chinese;
public double math;
public double english;
public double sumScore
{
get { return chinese + math + english;}
}
} } StudentList 類:
using System;using System.Collections.Generic;using System.Text;namespace Test2_6 {
public class StudentList:Student
{
int snums;
public Student[] stu=new Student[50];
public StudentList()
{
snums = 0;
}
public void addstu(Student s)
{
stu[snums] = s;
snums++;
}
public int searchstu(string name)
{
int i;
for(i = 0;i < snums;i++)
{
if(stu[i].name == name)break;
}
if(i == snums)return-1;
else return i;
}
//給所有成績排序,用后面實現前三名的排名
public void ProThree()
{
for(int i = 0;i < snums;i++)
{
int k = i;
for(int j = i + 1;j < snums;j++)
if(stu[j].sumScore > stu[k].sumScore)k = j;
if(k!= i)
{
Student temp;
temp = stu[k];
stu[k] = stu[i];
stu[i] = temp;
}
}
}
//顯示單科成績的最高分
public int HighScore(int k)
{
int p = 0;
if(k == 0)
{
for(int i = 1;i < snums;i++)
if(stu[i].math > stu[p].math)p = i;
}
else if(k == 1)
{
for(int i = 1;i < snums;i++)
if(stu[i].chinese > stu[p].chinese)p = i;
}
else
{
for(int i = 1;i < snums;i++)
if(stu[i].chinese > stu[p].chinese)p = i;
}
return p;
}
//顯示不及格名單
public string
BuhgName(int k)
{
string name=“ ”;
if(k == 0)
{
for(int i = 0;i < snums;i++)
if(stu[i].math < 60)name +=stu[i].name+“n”;
}
else if(k == 1)
{
for(int i = 0;i < snums;i++)
if(stu[i].chinese < 60)name += stu[i].name + “n”;
}
else
{
for(int i = 0;i < snums;i++)
if(stu[i].english < 60)name += stu[i].name + “n”;
}
return name;
}
public string getHL()
{
string Maxer = “ ”, Loser = “ ”;
Maxer += “ 單 科 數 學 最 高 :
” + stu[HighScore(0)].name + “n”;
Maxer += “ 單 科 語 文 最 高 :
” +
stu[HighScore(1)].name + “n”;
Maxer += “ 單 科 英 語 最 高 :
” + stu[HighScore(2)].name + “n”;
Loser += “單科數學掛科名單:” +BuhgName(0)+ “n”;
Loser += “單科語文掛科名單:” + BuhgName(1)+ “n”;
Loser += “單科英語掛科名單:” + BuhgName(2)+ “n”;
return Maxer + “n” + Loser;
}
//全班的平均成績
public string SumScore()
{
double sum = 0;
double avg=0;
for(int i = 0;i < snums;i++)
{
sum = sum + stu[i].sumScore;
}
avg = sum / snums;
return “班級總分平均分:”+avg;
}
//各科成績不同分數段的學生百分比
//英語成績各分數段百分比
public string PerC()
{
double per1, per2, per3, per4, per5;
double sumC1 = 0, sumC2 = 0, sumC3 = 0, sumC4 = 0, sumC5 = 0;
for(int i = 0;i < snums;i++)
{
if((stu[i].chinese > 90)&&(stu[i].chinese <= 100))
{
sumC1++;
}
else if((80 <= stu[i].chinese)&&(stu[i].chinese < 90))
{
sumC2++;
}
else if((70<=stu[i].chinese)&&(stu[i].chinese < 80))
{
sumC3++;
}
else if((60<=stu[i].chinese)&&(stu[i].chinese < 70))
{
sumC4++;
}
else
{sumC5++;}
}
per1 = sumC1 / snums;
per2 = sumC2 / snums;
per3 = sumC3 / snums;
per4 = sumC4 / snums;
per5 = sumC5 / snums;
return “ 語 文 成 績 百 分 比 :”+“n”+“90~100:”+per1+“
80~90:”+per2+“
80~70:”+per3+“
70~60:”+per4+“
以下的:”+per5;
}
//數學成績各分數段百分比
public string PerM()
{
double per1, per2, per3, per4, per5;
double sumC1 = 0, sumC2 = 0, sumC3 = 0, sumC4 = 0, sumC5 = 0;
for(int i = 0;i < snums;i++)
{
if((stu[i].math> 90)&&(stu[i].math <= 100))
{
sumC1++;
}
else if((80 <= stu[i].math)&&(stu[i].math < 90))
{
sumC2++;
}
else if((70 <= stu[i].math)&&(stu[i].math < 80))
{
sumC3++;
}
else if((60 <= stu[i].math)&&(stu[i].math < 70))
{
sumC4++;
}
else
{ sumC5++;}
}
per1 = sumC1 / snums;
per2 = sumC2 / snums;
per3 = sumC3 / snums;
per4 = sumC4 / snums;
per5 = sumC5 / snums;
return string.Format(“數學成績百分比:” + “n” + “90~100:” + per1 + “
80~90:” + per2 + “
80~70:” + per3 + “
70~60:” + per4 + “
以下的:” + per5);
}
//英語成績各分數段百分比
public string PerE()
{
double per1, per2, per3, per4, per5;
double sumC1 = 0, sumC2 = 0, sumC3 = 0, sumC4 = 0, sumC5 = 0;
for(int i = 0;i < snums;i++)
{
if((stu[i].english > 90)&&(stu[i].english <= 100))
{
sumC1++;
}
else if((80 <= stu[i].english)&&(stu[i].english < 90))
{
sumC2++;
}
else if((70 <= stu[i].english)&&(stu[i].english < 80))
{
sumC3++;
}
else if((60 <= stu[i].english)&&(stu[i].english < 70))
{
sumC4++;
}
else
{ sumC5++;}
}
per1 = sumC1 / snums;
per2 = sumC2 / snums;
per3 = sumC3 / snums;
per4 = sumC4 / snums;
per5 = sumC5 / snums;
return string.Format(“數學成績百分比:” + “n” + “90~100:” + per1 + “
80~90:” + per2 + “
80~70:” + per3 + “
70~60:” + per4 + “
以下的:” + per5);
}
} } From 窗體代碼:
using System;using System.Collections.Generic;
using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;namespace Test2_6 {
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public StudentList sl = new StudentList();
private void btnAdd_Click(object sender, EventArgs e)
{
Student s = new Student();
s.stuNo = txtStuNo.Text;
s.name = txtName.Text;
s.chinese = Convert.ToDouble(txtChina.Text);
s.math = Convert.ToDouble(txtMath.Text);
s.english = Convert.ToDouble(txtEng.Text);
sl.addstu(s);
MessageBox.Show(“添加成功”);
}
private void btnSearch_Click(object sender, EventArgs e)
{
int pos = sl.searchstu(this.textBox1.Text);
if(pos!=-1)
{
label7.Text = this.textBox1.Text + “的總成績:” + sl.stu[pos].sumScore;
}
else { MessageBox.Show(“不存在這個人!”);}
}
private void btnFinish_Click(object sender, EventArgs e)
{
label7.Text = “前 3 名:”+“n”;
for(int i = 0;i < 3;i++)
{
sl.ProThree();
label7.Text+= sl.stu[i].name+“n”;
}
label7.Text += sl.getHL()+“n”;
label7.Text += Convert.ToString(sl.SumScore())+“n”;
label7.Text += sl.PerC()+“n”;
label7.Text += sl.PerM()+“n”;
label7.Text += sl.PerE()+“n”;
}
} }
六、實驗體會(遇到問題及解決辦法,編程后的心得體會)
通過本次實驗,我掌握了類的定義與使用;掌握了類的數據成員,屬性的定義和使用;掌握了方法的定義,調用和重載以及方法參數的傳遞以及構造函數的定義和使用。值得注意的是:本次實驗中 return的使用以及所在的位置,類型轉換時也經常用到
實驗項目名稱:
繼承與多態
實驗學時:
同組學生姓名:
實驗地點:
1318
實驗日期:月 16 日-11 月 30 日 實驗成績:
批改教師:
批改時間:
實驗 3
繼承與多態
一、實驗目的、要求
(1)掌握類的繼承性與多態性;(2)掌握虛方法的定義以及如何使用虛方法實現多態;(3)掌握抽象類的定義以及如何使用抽象方法實現多態; 二、實驗要求
(1)編寫程序要規范、正確,上機調試過程和結果要有記錄;(2)做完實驗后給出本實驗的實驗報告。
三、實驗設備、環境
安裝有 Visual Studio.NET 軟件。
四、實驗步驟
1、分析題意; 2、根據題目要求,新建項目; 3、編寫并輸入相關的程序代碼; 5、運行與調試項目; 6、保存項目。
五、實驗內容
1、設計一個 Windows 應用程序,在該程序中首先構造一個學生基本類,再分別構造小學生、中學生、大學生派生類,當輸入相關數據,單擊不用的按鈕時,將分別創建不同的學生類對象,并輸出當前學生的總人數,該學生的姓名,學生類型,平均成績。
Student 類:
using System;using System.Collections.Generic;using System.Text;namespace Test3_1 {
public abstract class Student
{
protected string name;
protected int age;
public static int number;
public Student(string name, int age)
{
this.name = name;
this.age = age;
number++;
}
public string Name
{
get { return name;}
}
public abstract double Average();
}
public class Pupil : Student
{
protected double chinese;
protected double math;
public Pupil(string name, int age, double chinese, double math)
: base(name, age)
{
this.chinese = chinese;
this.math = math;
}
public override double Average()
{
return(chinese + math)/ 2;
}
}
public class Middle : Student
{
protected double chinese;
protected double math;
protected double english;
public Middle(string name, int age, double
chinese, double math, double english)
: base(name, age)
{
this.chinese = chinese;
this.math = math;
this.english = english;
}
public override double Average()
{
return(chinese + math + english)/ 3;
}
}
public class College : Student
{
protected double required;
protected double elective;
public College(string name, int age, double required, double elective)
: base(name, age)
{
this.required = required;
this.elective = elective;
}
public override double Average()
{
return(required + elective)/ 2;
}
} } Form 窗體內的代碼:
using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;namespace Test3_1 {
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnSmall_Click(object sender, EventArgs e)
{
Pupil p = new Pupil(txtName.Text,Convert.ToInt32(txtAge.Text),Convert.ToDouble(txtChinese.Text),Convert.ToDouble(txtMath.Text));
lblShow.Text += “ 總 人 數 :” +Convert.ToString(Student.number)+ “,” + “姓名:” + p.Name + “,” + “小學生” + “,” + “平均成績為:” + p.Average()+“n”;
}
private void btnMiddle_Click(object sender, EventArgs e)
{
Middle m = new Middle(txtName.Text, Convert.ToInt32(txtAge.Text), Convert.ToDouble(txtChinese.Text), Convert.ToDouble(txtMath.Text),Convert.ToDouble(TxtEnglish.Text));
lblShow.Text += “ 總 人 數 :” + Convert.ToString(Student.number)+ “,” + “姓名:” + m.Name +
“,” + “中學生” + “,” + “平均成績為:” + m.Average()+ “n”;
}
private void btnBig_Click(object sender, EventArgs e)
{
College c = new College(txtName.Text, Convert.ToInt32(txtAge.Text), Convert.ToDouble(txtChinese.Text), Convert.ToDouble(txtMath.Text));
lblShow.Text += “ 總 人 數 :” + Convert.ToString(Student.number)+ “,” + “姓名:” + c.Name + “,” + “大學生” + “,” + “平均成績為:” + c.Average()+ “n”;
}
} } 2、設計一個 Windows 應用程序,在該程序中定義平面圖形抽象類和派生類圓,矩形和三角形。
Figure 類代碼:
using System;using System.Collections.Generic;using System.Text;namespace Test3_2
{
public abstract class Figure
{
public abstract double Area();
}
public class Circle:Figure
{
double radius;
public Circle(double r)
{
radius = r;
}
public override double Area()
{
return radius * radius * 3.14;
}
}
public class JUxing:Figure
{
double chang;
double kuan;
public JUxing(double c, double k)
{
this.chang = c;
this.kuan = k;
}
public override double Area()
{
return chang * kuan;
}
}
public class San:Figure
{
double bian;
double heigth;
public San(double b, double h)
{
this.bian = b;
this.heigth = h;
}
public override double Area()
{
return bian * heigth / 2;
}
} } Form 窗體代碼:
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;namespace Test3_2 {
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnCircle_Click(object sender, EventArgs e)
{
Circle c=new
Circle(Convert.ToInt32(TxtChang.Text));
lblShow.Text = “圓的面積為:” + c.Area();
}
private void btnJu_Click(object sender, EventArgs e)
{
JUxing j = new JUxing(Convert.ToInt32(TxtChang.Text),Convert.ToInt32(TxtHigh.Text));
lblShow.Text = “矩形的面積為:” + j.Area();
}
private void btnSan_Click(object sender, EventArgs e)
{
San s = new San(Convert.ToInt32(TxtChang.Text), Convert.ToInt32(TxtHigh.Text));
lblShow.Text = “三角形的面積為:” + s.Area();
}
} }
3、定義一個 Person 類,包含姓名字段和一個方法,早上 8:30學生開始上課,教師開始講課。分別用 new 關鍵字,虛方法,抽象類實現多態性。
New 關鍵字:
using System;using System.Collections.Generic;using System.Text;
namespace third.three {
class Program
{
static void Main(string[] args)
{
Student s=new Student(“學生”);
Teacher t=new Teacher(“教師”);
Console.WriteLine(s.name+s.work());
Console.WriteLine(t.name+t.work());
Console.ReadLine();
}
}
public class Person
{
public string name;
public interface method
{ string work();}
}
public class Student:Person
{
public Student(string name)
{ this.name = name;}
public string work()
{ return “早上 8:30 開始上課”;}
}
public class Teacher:Person
{
public Teacher(string name)
{ this.name = name;}
public string work()
{ return “開始講課”;}
} } 虛方法:
using System;
using System.Collections.Generic;using System.Text;
namespace third.three.two {
class Program
{
static void Main(string[] args)
{
Student s = new Student(“張三”,“學生”);
PersonWork(s);
Teacher t=new Teacher(“李斯”,“教師”);
PersonWork(t);
}
private static void PersonWork(Person Person)
{ Console.WriteLine(Person.Work());}
}
public class Person
{
public string name;
public Person(string name)
{ this.name = name;}
public virtual string Work()
{ return string.Format(“Person{0}:早上 8:30 開始”,name);}
}
public class Student : Person
{
private string type;
public Student(string name, string type)
: base(name)
{ this.type = type;}
public override string Work()
{
return string.Format(“Person{0}:早上 8:30 開始上課”, name);
}
}
public class Teacher : Person
{
private string type;
public Teacher(string name, string type)
: base(name)
{ this.type = type;}
public override string Work()
{
return string.Format(“Person{0}:開始講課”, name);
}
} }
抽象類:
using System;using System.Collections.Generic;using System.Text;
namespace third.three.three {
class Program
{
static void Main(string[] args)
{
Student s = new Student(“張三”, “學生”);
PersonWork(s);
Teacher t = new Teacher(“李斯”, “教師”);
PersonWork(t);
}
private static void PersonWork(Person person)
{
Console.WriteLine(person.Work());
}
}
public abstract class Person
{
public string name;
public Person(string name)
{ this.name = name;}
public abstract string Work();
}
public class Student : Person
{
private string type;
public Student(string name, string type)
: base(name)
{
this.type = type;
}
public override string Work()
{
return string.Format(“Person{0}:早上 8:30 開始上課”, name);
}
}
public class Teacher : Person
{
private string type;
public Teacher(string name, string type)
: base(name)
{
this.type = type;
}
public override string Work()
{
return string.Format(“Person{0}:開始講課”, name);
}
}
}
六、實驗體會(遇到問題及解決辦法,編程后的心得體會)
通過本次實驗,我理解了類的繼承性與多態性;掌握了虛方法的定義以及如何用虛方法來實現多態;掌握了抽象類的定義以及如何用抽象方法來實現多態。
這次實驗與前兩次不同,采用 Windows 應用程序,既涉及到代碼段也涉及到界面的設計。所以,勉強通過實驗。
實驗項目名稱:
接口、文件和流
實驗學時:
同組學生姓名:
實驗地點:
A205
實驗日期:月 7 日-12 月 21 日 實驗成績:
批改教師:
批改時間:
實驗 4
接口、文件和流
一、實驗目的
(1)掌握接口的定義及使用方法;(2)掌握流,序列化和反序列化的概念和使用方法;(3)掌握流文件的讀寫操作類及其使用方法;(4)掌握 OpenFileDialog,SaveFileDialog 等控件的使用。
二、實驗要求
(1)編寫程序要規范、正確,上機調試過程和結果要有記錄;(2)做完實驗后給出本實驗的實驗報告。
三、實驗設備、環境
安裝有 Visual Studio.NET 軟件。
四、實驗步驟
1、分析題意; 2、根據題目要求,新建項目; 3、編寫并輸入相關的程序代碼; 5、運行與調試項目; 6、保存項目。
五、實驗內容
1、定義一個 Person 類,包含姓名字段和一個方法,早上 8:30學生開始上課,教師開始講課。用接口來實現。
using System;using System.Collections.Generic;
using System.Text;namespace Test4_1 {
class Program
{
static void Main(string[] args)
{
Student s = new Student(“張三”,“學生”);
Console.WriteLine(s.Work());
Teacher t = new Teacher(“李四”,“老師”);
Console.WriteLine(t.Work());
}
public abstract class Person
{
public string name;
public Person(string name)
{
this.name = name;
}
}
interface IPerson
{
string type { get;}
string Work();
}
public class Student :Person, IPerson
{
public string type
{
get { return string.Format(“老師”);}
}
public Student(string name, string type)
: base(name)
{
this.name=name;
}
public string Work()
{
return string.Format(“Person{0}:早上 8:30 開始上課”, name);
}
}
...
第四篇:C#實習總結
現在的社會日新月異,科技飛速發展,但是隨之而來的環境問題也日益嚴重,當然這也有很多其他諸如人口、能源等因素,不過這些讓人們越來越重視綠色產業,而軟件就是首當其沖的一個。我積極參加了學校組織的軟件實習,主要是對.Net方面的實訓和實戰,一方面想要繼續深造之前在大學里面學習的軟件方面的知識,另一方面,也是為了自己的職業規劃,說直接點,就是以后找份好工作。雖然實訓中時間安排有點緊,但很充實,學到了很多之前在大學課堂上沒有學到的知識,可以說我從這次實訓中的收獲很大。
對于計算機編程,我可以說從高中就開始接觸,大學從專科開始一直學習的都是軟件開發的專業,學過C#、Java,學過開發,也學過測試。但是這次實訓讓我體會了和之前完全不同的學習感受,不僅是時間安排、或者說效率還是教學授課的方式上,都是和大學課堂完全不同的,不是一節課講一點,也不是一點一點教給你,這個實訓中更多的是培養我們獨立動手解決實際問題的能力,分析考慮問題的方法思路,讓我們真正成長起來。
學校為我們提供了良好的學習的平臺,提供了好工作的面試機會。我們覺得我們更應該充分利用資源,珍惜機會,努力學習,不斷地給自己“充電”,這樣才能不斷的開拓進取,勇于創新,才不至于被社會淘汰。
這次實習中,我們主要有S0、S1、S2三個階段,S0階段主要是自學C#基礎知識,S1階段是在老師的指導下學習C#基礎編程、C#桌面應用開發、C#數據庫應用開發、C#網絡應用開發、軟件測試和軟件工程幾個方面的技術方面的課程,S2階段則是進入項目實戰,做實際項目來進行鞏固和總結。整個過程中,還有穿插了職業素養課和英語口語課,學技術的同時,我們也注重職業素養的培養和英語口語的鍛煉。
到目前為止,我們實習的主要成果有(按時間順序):Point24(24點游戲求解小程序)、HandsUp(舉手游戲模擬小程序)、SimpleCalculator(簡單計算器)、GottaU(捕捉鼠標小游戲)、TypeGame(打字小游戲)、WebBrowser(簡易網絡瀏覽器)、Checker(單機對戰跳棋小游戲)、MDITextEditor(多文檔界面文本編輯器)、FileManager(文件管理器)、SimpleMediaPlayer(簡單媒體播放器)等,這些小程序或是項目,雖然和市面的那些軟件比起來,在功能強大、界面美觀、Bug稀少等方面都有欠缺,但是都是實打實的,我們自己動腦、動手做出來的,當然在做的過程中遇到了不少困難、挫折,但是正因為這些困難和挫折,我們才真正學到了知識和技術。更值得注意的則是,在老師帶領我們做項目的過程中,我們從老師的言傳身教中學到了很多很多編程思想、解決問題的方法思路等各種“無形”的知識。
眾多收獲之中,讓我感觸頗深的,則是老師給我們介紹的“10-90”原則和“Quality-Client-Cost”原則。“10-90”原則的意思是,我們通常都是花10%的代價就可以完成一件事或者一個項目的90%,而剩下的10%,卻需要我們花費90%的金錢、精力等各種代價,能不能做到這最后的10%,往往是衡量一個人或者一家公司很重要的一個原則。而且這個原則還是可以嵌套的,最后10%的部分中,也可以再分成90%和10%,同樣是開始的90%需要10%的代價,最后的10%需要90%的代價。這個原則不僅適用于做軟件、做項目、做公司,其實人生中做人也是如此,很多時候最后的10%是很重要的一把標尺。雖然不能說這個原則放之四海而皆準,但是確實是適用于很多地方、很多方面,讓我獲益良多。“Quality-Client-Cost”原則講的則是做軟件或是做軟件公司的一個原則,就是質量一定要放在第一位,客戶在第二位。我自己原本心目中對這三項的排序是Client-Quality-Cost”,但是老師的講解點醒了我,最具有說服力的例子,就是像微軟這樣的大公司,都是Quality第一的,他們寧可花費多一些,價格貴一些,但是一定把產品盡善盡美。這個原則同樣可以用在人生中,Quality就是人品、品德、素質,Client是朋友、客戶、親人,我們當然應該把個人的品格放在第一位。這些都屬于這次實習中,我在技術以外的收獲。
另外在實習還有職業素養課中,也學到了很多其他在今后的工作中,要注意的東西,首先要有團隊合作精神,現金的大中型軟件的編寫,分工越來越細,這樣在開發、測試的過程中,團隊的合作、成員間的交流就變得尤為重要,是決定效率的重要因素;要學會獨立解決問題,工作不比在學校學習,遇到的各種實際問題不會有老師專門幫助解決,自己獨立分析、解決問題的能力就變得極其重要;要有創新精神,在工作和學習中,如果只是一味的模仿、學習,那就永遠不會真正得學得得心應手、融會貫通,必須自己去實踐,在實踐中創新,這樣才能把學來的,變成自己的;要有耐心,學會自我規劃和管控,耐心自是不必多說,有耐心才能把事情仔細做好,而公司的管理制度和學校根本上的不同,使得自我規劃和管控就成了能否按時圓滿完成任務的很重要的條件。
通過這次實習,我在個人素質方面有較大的提高,不僅是在C#的技術方面,還包括面對、分析和處理問題的思路、能力,思維的創造性和全面性,交流和溝通能力,英語口語水平,同時也克服了一些自己的缺點,獲得很大進步。
總的來說,這次實習對我有很大意義,不僅鞏固和實踐了之前在大學課堂上學到的各種知識,擴充了自己對軟件技術方面的知識儲備,同時也給了我很大的成就感,增強了我的自信。并不是說因為我做成的很難的程序,或者做出來的軟件很強很完善,但都是自己認真完成的,過程中有遇到各種困難和挫折,但是經
過網上查資料、小組討論、向老師請教等幾種途徑,最終都克服了,當最終自己完成時,總會有一些成就感。
此外,我還人知到在以后的工作和學習中,不僅要努力學習和鍛煉專業技能知識,包括C#技術、算法技巧、MVC模式框架的開發、中間技術等等,而且也要注意讓自己興趣廣泛起來,拓寬自己的知識面,多積累各種知識,這不僅對以后的軟件開發工作有一定好處,對自身的個人修養的提升也是大有裨益。
社會的競爭是激烈的,我想我們應該好好把握住大學學習的時間,充實、完善自我,掌握更多的專業知識,加強實踐和設計能力,同時也注意全面發展,這樣更有利于將來的發展,在自己的專業領域有所作為。
第五篇:C#期末總結
C#期末總結
接觸C#已經有半學期時間,對C#感觸頗多。C#作為邏輯性極強,功能強大的程序編程語言,僅僅學習半學期是遠遠不夠的,希望自己能在這條路上不斷前行,能夠活到老學到老。
跟絕大部分的初學者一樣,當看見密密麻麻的代碼,就覺得這會是一門枯燥無味的課程。但在平時生活中使用各種功能強大的app,應用程序等時,我又會對程序背后的代碼感到好奇。就是在這樣矛盾的心情中,我一點點初步掌握了C#。
C#中最難理解也是最有意思的莫過于類的使用了。總的來說類是屬性相同的方法或對象的集合。編程語言中的類較為抽象,難以理解。編程語言中類的思想在現實生活有許多體現。比如我們通常會把馬路上所有的四輪交通工具歸為一類----汽車,在生物學中也使用界、門、綱、目、科、屬、種把所有生物分級分類。似乎這樣想,類很好理解。但在具體編程中會遇到許多問題,比如類成員中各個成員變量的訪問權限問題以及類與類之間的邏輯關系問題,等等。解決這些問題,需要對事物和目標有準確的理解和把握,當然扎實的C#功底基礎也是必不可缺的。如果能夠充分使用類,那么代碼的編寫會變得井井有條,至少代碼會看上去富有生命力。
編程的過程自然枯燥無味,但當看見自己編寫的程序運行成功,那種滿足感不言而喻。例如本學期的貪吃蛇游戲編程過程,就讓我感觸頗深。(首先必須承認的一點就是貪吃蛇游戲的主體代碼是我借鑒網上大神,光是看懂捋清大神的代碼就花了我一星期的時間,接下來就是添加完善代碼)首先想要在游戲開始之前添加一個難度選擇功能界面,這就必須解決兩個問題:一個是怎樣控制兩個界面(難度選擇界面和游戲界面)出現先后次序問題,另一個是如何保存已經選好的難度選擇并在游戲中體現出來。對于第一個問題我的解決方案如下:先在speed.cs(難度選擇代碼區)文件中加入”this.Close();”語句;再在program.cs(程序的主入口)文件中加入”Application.Run(new Speed());”和”Application.Run(new form());”語句。加入”this.Close();”語句的目的是當難度選擇完成后讓難度選擇界面自行關閉;加入”Application.Run(new Speed());”和”Application.Run(new form())”的目的是控制兩個界面先后出現的次序。這個問題的解決過程還算順利,它主要涉及函數調用。第二個問題的解決就比較難,大概耗費我兩星期的時間。第二個問題屬于在類與類之間調用變量問題。這一類問題在各種編程中會常常遇到。通過查各種資料和不斷試驗,我的解決方案如下:先添加一個新類PublicClass,然后在PublicClass定義一個靜態變量z,再在主代碼區調用z。添加新類的目的是使代碼簡潔明了并方便后期修改,定義變量z的目的是將難度選擇值賦給z。這兩個問題解決使得貪吃蛇程序能夠順利運行。但順利運行并不代表這是一個合格的程序,同學反映說這個程序看上去并不是很美觀,我意識到還需要在用戶體驗方面下工夫,沒想到這給我帶來不小的麻煩。我的計劃是用圖片代替方塊來顯示蛇身,但我錯誤以為只要將定義方塊的函數修改成繪畫圖片的函數就可以了,導致的結果就是程序運行崩潰。我不斷翻看所有的代碼,一遍又一遍試驗,但都找不到解決的辦法。就這樣過了三四天的時間,我甚至有了放棄的打算。但或許是印證了那句話“山重水復疑無路,柳暗花明又一村”,主代碼中有段注釋引起了我的注意------”//畫出方塊并顯示在畫板上”,這時我才恍然大悟:原來不管是方塊還是圖片都要定義并使用draw()才能在界面上顯示出來,定義方塊的函數只不過定義了最基本的方塊屬性(形狀,顏色,大小等)。如果需要更換蛇身圖片,只需要在”draw()”中更改就可以了(因為圖片是從網上下載,圖片的各個屬性已固定無需再定義)。最終成功的給蛇換上了一件”新衣服”,程序的用戶體驗性大大提升。
完成貪吃蛇的編程后,我深深體會到C#是一款面向對象的編程語言。把解決問題的各個因素分門別類,實現分工合作以達到高效率的解決問題。就像現實中的社會分工一樣,每個人都在各自的崗位上辛勤勞動,無論工作大小,國家社會離不開每個人的奉獻付出。C#中還有其他有趣的控件,比如timer,picturebox,textbox等。靈活組合這些控件,能夠編寫出很多有意思的小程序。曾經看見網上有C#計算器,C#計時器的教程,覺得很有意思并嘗試了一下,但發現很難實現程序,究其原因是因為作者的思維與我的思維有著很大的不同,這說明每個人解決問題的方式不同,而程序便是程序員思維的體現。每個自己編寫的程序都是與自己的思維相通的,這么理解的話可以把程序看成自己思維在其他事物上的拓展,其樂無窮,樂此不疲。或許這就是為什么世界上有那么多的天才編程員愿意夜以繼日的編寫程序,或許這也就是為什么好萊塢每每拍出人工智能統治世界的科幻片總能席卷全球票房。名偵探柯南劇場版《貝克街的亡靈》中的超級人工智能諾亞方舟在天才計算機少年澤田弘樹死后代替其意志繼續在日本存活下去。想想確實可怕,人工智能究竟會改變人多少。計算機注定改變每個人的生活。因此掌握計算機無疑就是掌握了未來。
由于半學期的學習時間實在太少,想要深刻理解并靈活運用C#是需要多年的實踐學習的。光是上課時間認真聽講是遠遠不夠的,還需要課下不斷的練習鉆研。學習c#語言不能停留在學習它的語法規則,而是利用學到的知識編寫c#語言程序,解決實際問題。即把c#語言作為工具,描述解決實際問題的步驟,由計算機幫助我們解題。只有通過上機才能檢驗自己是否掌握c#語言、自己編寫的程序是否能夠正確地解題。語法是學習編程語言的關鍵,光靠背語法,是遠遠不夠的(其他語言學習也是如此)。記筆記是上課時候必須要做的一件事,但不能認為做了筆記就不用上課認真聽講了。C#作為一名理科學科是需要不斷深入理解實踐才能掌握的。有幾點學習心得想分享一下:.不要妄自菲薄。不能因為遇到困難就不相信自己,每個人都是從零開始。2.堅持不懈。學習C#是件漫長的過程,需要不斷激勵自己鼓勵自己。
3.多和他人交流。一個人的力量是渺小的,多個人相互交流不斷切磋才能不斷進步。4.不要偷懶,經常思考。C#中有許多思想是和現實生活相通的,不斷對生活感悟對生活進行反思,從生活中尋找靈感,這樣能提高對C#的興趣以及學習的主動性和趣味性。
5.經常上機實驗,動手操作。實踐出真知,在實踐中理解那些深奧晦澀難懂的專業知識。6.在編程時除了要認真謹慎之外,更重要的是掌握基本的知識,比如if語句和while語句的區別。初學者常常會被這兩個語句搞得暈頭轉向,在編程過程也不會太在意兩個語句的使用范圍。再比如C#中命名空間,這是常常忽略的方面,初學者一開始編程時會發現定義一個變量或者函數常常會遇到系統提醒錯誤,開始認真檢查下來,卻怎么也找不到錯在哪,這很有可能就是命名空間錯誤。
大學之前從未接觸編程語言,對于C#的學習也是在一時興起和懷疑自己中不斷轉換。平時會去圖書館借些C#書籍,但總有種意猶未盡的感覺。這種感覺或許來自對編程語言的興趣,希望自己能學到更多關于編程語言的知識。