C#学习笔记(4)深入理解类下
4.8构造函数
(跟C++的构造函数基本一致所以接下来就直接给出代码就不详细讲解)
代码:
using System; class Student { string m_name; int m_id; public Student() { m_name = "NO Student"; m_id = 0; } public Student(string name, int id) { m_name = name; m_id = id; } public void display() { Console.WriteLine($"Name: {m_name} Id: {m_id}"); } } class Program { static void Main() { Student a = new Student(); Student b = new Student("Lijiaqin", 218228); a.display(); b.display(); } }
代码:
using System; class Student { string m_name; int m_id; public static int number; public static void fir() { number = 1; } public Student() { m_name = "NO Student"; m_id = 0; number++; } public Student(string name, int id) { m_name = name; m_id = id; number++; } public void display() { Console.WriteLine($"Name: {m_name} Id: {m_id} Number: {number}"); } } class Program { static void Main() { Student.fir(); Student a = new Student(); a.display(); Student b = new Student("Lijiaqin", 218228); b.display(); } }
4.9析构函数
C#有自己的垃圾回收机制,不需要为类写出析构函数
4.10 readonly修饰符
字段可以用readonly修饰符声明。其作用类似于将字段声明为const,一旦值被设定就不能改变。
(1)const字段只能在字段的声明语句中初始化,而readonly字段可以在下列任意位置设置它的值。
(2)const字段的值必须可在编译时决定,而readonly字段的值可以在运行时决定。这种自由性允许你在不同的环境或不同的构造函数中设置不同的值。
(3)它可以是实例字段,也可以是静态字段,它在内存中有存储位置。
4.11 this关键字
this关键字在类中使用,是对当前实例的引用。它只能被用在下列类成员的代码块中。
(1)实例构造函数。
(2)实例方法
(3)属性和索引器的实例访问器(索引器将在下一节阐述)。
注:因为静态成员不是实例的一部分,所以不能在任何静态函数成员的代码中使用this关键字。更适当地说,this用于下列目的:
(1)用于区分类的成员和局部变量或参数;
(2)作为调用方法的实参。
例如,下面的代码声明了类MyClass,它有一个int字段和一个方法,方法带有一个单独的int参数。方法比较参数和字段的值并返回其中较大的值。唯一的问题是字段和形参的名称相同,都是var1。在方法内使用this关键字引用字段,以区分这两个名称。
class MyClass
{
int var1 =10;
public int ReturnMaxSum ( int var1)
{
Return var1 > this.var1 ? var1 : this.var1; //var1是参数,var1是
}
}
4.12 索引器
4.12.1索引器的引入


4.12.2索引器的声明
声明索引器的语法如下所示。请注意以下几点。
(1)索引器没有名称。在名称的位置是关键字this。
(2)参数列表在方括号中间。
(3)参数列表中必须至少声明一个参数。
形如:
ReturnType this(关键字) [Type param 1 , ……](参数列表)
{
get
{
……
}
set
{
……
}
}
4.12.3索引器和属性的对比
索引器和属性在很多方面是相似的。
(1)和属性一样,索引器不用分配内存来存储。
(2)索引器和属性都主要被用来访问其他数据成员,它们与这些成员关联,并为它们提供取和设置访问。属性通常表示单个数据成员。索引器通常表示多个数据成员。
说明:可以认为索引器是为类的多个数据成员提供get和set访问的属性。通过提供索引器,可以在许多可能的数据成员中进行选择。索引本身可以是任何类型,而不仅仅是数值类型。
关于索引器,还有一些注意事项如下。
(1)和属性一样,索引器可以只有一个访问器,也可以两个都有。
(2)索引器总是实例成员,因此不能被声明为static。
(3)和属性一样,实现get和set访问器的代码不一定要关联到某个字段或属性。这段代码可以做任何事情也可以什么都不做,只要get访问器返回某个指定类型的值即可。

4.12.4索引的set 与get访问器
set:
当索引器被用于赋值时,set访问器被调用,并接受两项数据,如下:
(1)一个名为value的隐式参数,其中持有要保存的数据;
(2)一个或更多索引参数,表示数据应该保存到哪里。
形如:emp[0]="Doe";
set访问器有如下语义:
(1)它的返回类型为void。
(2)它使用的参数列表和索引器声明中的相同。
(3)它有一个名为value的隐式参数,值参类型和索引器类型相同。
get:
当使用索引器获取值时,可以通过一个或多个索引参数调用get访问器。索引参数指示获取哪个值。
形如:
string s=emp[0];
get访问器方法体内的代码必须检查索引参数,确定它表示的是哪个字段,如果get是以普通方法的语法书写的。get访问器有如下语义。
(1)它的参数列表和索引器声明中的相同。
(2)它返回与索引器类型相同的值。
4.12.5代码展示:
下面的代码为先前示例中的类Employee声明了一个索引器。
(1)索引器需要读写string类型的值,所以string必须声明为索引器的类型。它必须声明为public,以便从类的外部访问。
(2)3个字段被随意地索引为整数0-2,所以本例中方括号中间名为index的形参必须为int型。在set访问器方法体内,代码确定索引指的是哪个字段,并把隐式变量value的值赋给它。
(3)在get访问器方法体内,代码确定索引指的是哪个字段,并返回该字段的值。
代码1:
class Employee { public string LastName;//调用字段0 public string FirstName;//调用字段1 public string CityOfBirth ;//调用字段2 public string this[int index]//索引器声明 { set//set访问器声明 { switch(index) { case 0: LastName = value; break; case 1: FirstName = value; break; case 2: CityOfBirth = value; break; default://(异常以后再聊) throw new ArgumentOutOfRangeException ("index"); } } get//get访问器声明 { switch(index){ case 0: return LastName; case 1: return FirstName; case 2: return CityOfBirth ; default://(异常) throw new ArgumentOutOfRangeException ("index"); } } } }
代码2(这个代码有点问题):
class Class 1 { int Temp0;//私有字段 int Temp1;//私有字段 public int this[int index]//索引 { get { return(0==index? Temp0:Temp1;) } set { if (0== index) Temp0=value;//注意隐式变量"value" else Temp1=value;//注意隐式变量"value" } } } class Example { static void Main() { class1 a=new class1(); Console. Writeline("Values--TO:{0},T1:{1}",a[0],a[1]); a[0]=15; a[1]=20; Console.WriteLine($"Values--TO:{a[O]},T1:{a[1]}");} } } 代码运行结果: Values--T0: 0, T1:0; Values--T0: 15, T1:20;

浙公网安备 33010602011771号