结构体主要用于创建小型对象,因为在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 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(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 (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 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);