Fork me on GitHub

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;

 

 

 

 

posted @ 2022-06-30 11:19  衔清风与共  阅读(104)  评论(0)    收藏  举报