《C#程式設計經典300例》讀書筆記
語法基礎
結構體主要用於建立小型物件,因為在C#中值型別是儲存線上程堆疊中的,而執行緒堆疊的預設大小是1MB。
交錯陣列
byte[][] months = new byte[12][];
if (month % 2 == 0) {
months[month] = new byte[31];
} else {
months[month] = new byte[30];
}
Dictionary
//建立省份列表
Dictionary<string, List<string>> provinces = new Dictionary<string , List<string>>();
//建立河北省
List<string> HeBei = new List<string>();
//將河北省新增到省份列表中
provinces.Add("河北", HeBei);
//新增城市
HeBei.Add("石家莊");
//新增城市
HeBei.Add("唐山");
Queue
先進先出,Stack
先進後出。
字串
如果需要刪除某個字串,可以使用Replace
方法,將其第一個引數傳入需要刪除的字串,第二個引數輸入string.Empty
即可。
Contains
(判斷字串中是否含有指定字串)、StartsWith
EndWith
(判斷字串是否以指定字串結尾)在模糊匹配中作用很大。
資料結構與演算法
索引器
public class StudentList {
//學生資訊順序表
private Student[] Students;
//檢索學生資訊表
public Student this[int index] {
get {
return Students[index];
}
set {
Students[index] = value;
}
}
}
int?
表示可空型別,就是一種特殊的值型別,它的值可以為null
;int??
用於判斷並賦值,先判斷當前變數是否為null
,如果是就可以賦役個新值,否則跳過。
類與結構
在外部訪問靜態屬性時必須在類名後加“.”再加上屬性名稱,如Car.Number
。
可以利用this
關鍵字通過第一個建構函式來實現第二個建構函式,程式碼如下:
public Date(DateTime datetime): this(datetime.Year,datetime.Month,datetime.Day){}
宣告類或結構的索引器必須使用this
關鍵字
//學科分數索引器
public int this[int index] {
//獲取指定索引科目的分數
get {
return scores[index];
}
//設定指定索引科目的分數
set {
scores[index]=value;
}
}
屬性的最大好處在於可以通過設定get
和set
的訪問級別來限制訪問器的訪問。例如:
public string City {
public get {
return city;
}
private set {
city=value;
}
}
其中的City
屬性值只能由類的內部進行分配,外部只能獲取到City
的值。從程式碼中還可以看到,在set
訪問器中通過value
關鍵字來定義分配的值。其實屬性中的get
和set
不一定要同時存在。如果只允許訪問該屬性的值,則可以只保留get
訪問它。同理,如果只允許設定該屬性的值,則可以只保留set
訪問器。當屬性的訪問器中不需要其他邏輯時,可以使用C#中自動實現的屬性。例如:
public string City{get;set;}
自動實現屬性時,get
和set
必須同時出現。如果不需要外部來修改屬性值,可以在set
前面加上private
修飾符。例如:
public string City(get;private set;}
通常,在派生類中通過base
關鍵字來呼叫基類中公有的或受保護的成員。還可以在派生類的建構函式中通過base
關鍵字來呼叫基類的建構函式。例如:
public Panda(string food): base(“熊貓”,food){}
在派生類中可以使用base
關鍵字呼叫基類中的方法。
在類定義前使用abstract
關鍵字可以將類宣告為抽象類。例如:
abstract Class Student{}
在方法的返回型別前面使用abstract
關鍵字可以將方法宣告為抽象方法。例如:
public abstract int Authority();
抽象方法是沒有具體的方法實現,直接在方法名後使用“;”結束定義。
在抽象類的派生類中必須實現該抽象類中的抽象方法。例如:
public override int Authority() {
return 5;
}
如果在抽象類的派生類中不實現抽象方法,那麼該派生類也必須宣告為抽象類。
事件
class CallEventArgs: EventArgs{}
class Phone {
//來電提醒事件
public event EventHandler<CallEventArgs> CallAlert;
//來電
public void Call(long number) {
if (CallAlert != null) {
//觸發來電提醒事件
CallAlert(this, new CallEventArgs(number));
}
}
}
class Program {
static void Main(string[] args) {
Phone phone = new Phone(13888888888);
//新增來電提醒事件
phone.CallAlert += new EventHandler<CallEventArgs>(phone_CallAlert);
phone.Call(13999999999);
}
//來電提醒事件函式
static void phone_CallAlert(object sender, CallEventArgs e) {
Phone phone = sender as Phone;
}
}
在定義事件時需要使用event
關鍵字,EventHandler
委託表示事件處理方法將要遵循的格式,CallEventArgs
型別表示EventHandler
的第二個引數型別,該型別必須派生自系統提供的EventArgs
類。CallAlert
則為事件名稱。
基類事件
class Program {
static void Main(string[] args) {
//建立圓形例項
Circle circle = new Circle(100);
circle.SharpChanged +=
new EventHandler<SharpChangedEventArgs> (Sharp_SharpChanged);
//修改圓形的半徑
circle.Radius = 50;
}
static void Sharp_SharpChanged(object sender, SharpChangedEventArgs e) {
if (sender is Circle) ;
else if (sender is Rectangle) ;
}
}
//形狀改變事件引數類
class SharpChangedEventArgs : EventArgs {
//改變後的面積
public readonly double Area;
public SharpChangedEventArgs(double area) {
Area = area;
}
}
//形狀
class Sharp {
//形狀的面積
public double Area {
get;
protected set;
}
//形狀改變事件
public event EventHandler<SharpChangedEventArgs> SharpChanged;
//形狀改變虛擬函式
protected virtual void OnSharpChanged(SharpChangedEventArgs e) {
if (SharpChanged != null) {
//觸發形狀改變事件
SharpChanged(this, e);
}
}
}
//圓形
class Circle: Sharp {
int radius;
//圓形半徑
public int Radius{
get {
return radius;
}
set {
//如果半徑發生變化
if (radius != value) {
radius = value;
//重新計算面積
Area = Math.PI * radius * radius;
OnSharpChanged(new SharpChangedEventArgs(Area));
}
}
}
public Circle(int radius) {
this.radius = radius;
//計算圓形面積
Area = Math.PI * radius * radius;
}
protected override void OnSharpChanged(SharpChangedEventArgs e) {
//過載形狀改變函式
base.OnSharpChanged(e);
}
}
本例項程式碼主要實現了在派生類中引發基類的事件。由於事件是特殊型別的委託,派生類無法呼叫基類中宣告的事件。因此,只有通過在基類中定義事件和引發該事件的虛方法,然後在派生類中通過呼叫基類中定義的引發事件的虛方法來間接呼叫該事件。
委託
class Program {
static void Main(string[] args) {
StudentTable table = new StudentTable();
//顯示錶中所有男生資訊
table.Display(Display);
}
//顯示男生資訊
static void Display(Student student) {}
}
//顯示學生資訊委託
delegate void DisplayStudent(Student student);
//學生資訊表類
class StudentTable {
//顯示學生資訊
public void Display(DisplayStudent display) {
foreach (Student student in students) {
display(student);
}
}
}
該委託的使用很好地實現了學生資訊的顯示方式與學生資訊表的分離。在需要將方法與委託進行繫結時,就需要例項化委託。例如:
DisplayStudent display = new DisplayStudent(Display);