C#[1]this关键字和索引器
来源:互联网 发布:细说php第二版电子书 编辑:程序博客网 时间:2024/06/08 08:09
一、this关键字
在C#中,this关键字有以下3种常见的用法:
1.用在类的属性、实例方法或实例构造方法中,区分成员名和本地变量(或参数)。下面的示例声明一个名为Myclass的类,类中包括一个实例字段myVal和一个实例构造函数,该构造函数带一个名为myVal的参数,在方法中,通过this可以在语义上区分成员名myVal和参数名myVal。(注意:在实际编程中是不建议参数名和字段名相同的,这样做降低了代码的易读性,这里只是为了说明this关键字的用法而已)。
class MyClass { // 声明一个名为"myVal"的整型字段 public int myVal = 10; // 声明一个构造函数,该函数带一个名为"myVal"的参数 public MyClass(int myVal) { // "this"表示MyClass类的当前实例 // 在这里通过this可以在语义上区分成员名myVal和参数名myVal this.myVal += myVal; } }2.this表示的是当前对象,可以把它作为实参传递到其它方法。例如下面声明一个类MyClass1,它包括一个实例成员方法Compute,而Compute带一个类型为MyClass的参数,该参数在方法中参加运算。
class MyClass1 { // 声明一个计算的方法,参数类型为MyClass public static int Compute(MyClass mc) { int resutl = 0; if (mc != null) { resutl += mc.myVal; } return resutl; } }下面在类MyClass的构造方法中添加了一个本地变量的声明,该变量初始化的值来自MyClass1的Compute方法的计算结果。而这时就可以将this作为实参传递给调用方法了:
class MyClass { // 声明一个名为"myVal"的整型字段 public int myVal = 10; // 声明一个构造函数,该函数带一个名为"myVal"的参数 public MyClass(int myVal) { // "this"表示MyClass类的当前实例 // 在这里通过this可以在语义上区分成员名myVal和参数名myVal this.myVal += myVal; // 使用this作为当前对象的实参传递给Compute方法 int res = myVal + MyClass1.Compute(this); } }
3.声明索引器。接下来在第二部分当中分析索引器的声明和使用方法。
此外,应当注意的一点:由于静态成员函数存在于类一级,并且不是对象的一部分,没有 this 指针,因此不能在静态方法中使用this关键字。在静态方法中引用 this 是错误的。
二、索引器
1.通过点运算符访问实例成员
一般情况下,我们是通过点运算符(“实例名.成员名”)的方式来访问类的实例成员的。比如下面的示例,该例中其实是通过调用属性的set访问器为成员字段赋值,并且通过get访问器读取成员字段的值的。
class Course { public float Chinese { set; get; } public float Math { set; get; } public float Englisth { set; get; } } class Program { static void Main(string[] args) { // 声明一个Course类的实例 var course = new Course(); // 使用传统的“实例名.成员名”方式访问成员 // 赋值 course.Chinese = 95; course.Math = 100; course.Englisth = 80; // 取值 Console.WriteLine("语文:{0},数学:{1},英语:{2}", course.Chinese, course.Math, course.Englisth); Console.ReadKey(); } }
2.通过索引器访问实例成员
通过观察上面示例的代码,可以发现:该类的所有成员具有相同的类型float,它们其实可以像访问数组一样的方式访问,所以,我们可以为类提供另一种实例成员访问方式:索引器。下面的代码为上面的Course类声明加上了一个float类型的索引,并在Main方法中通过索引存取数据:
class Course { public float Chinese { set; get; } public float Math { set; get; } public float Englisth { set; get; } // 声明一个公开的float类型的索引器 public float this[int index] { // set访问器:赋值 set { switch (index) { case 0: this.Chinese = value; break; case 1: this.Math = value; break; case 2: this.Englisth = value; break; default: // 索引越界时抛出异常 throw new ArgumentOutOfRangeException(); } } // get访问器:取值 get { switch (index) { case 0: return this.Chinese; case 1: return this.Math; case 2: return this.Englisth; default: throw new ArgumentOutOfRangeException(); } } } } class Program { static void Main(string[] args) { // 声明一个Course类的实例 var course = new Course(); // 使用索引器访问实例成员 // 赋值 course[0] = 95; course[1] = 100; course[2] = 80; // 取值 Console.WriteLine("语文:{0},数学:{1},英语:{2}", course[0], course[1], course[2]); Console.ReadKey(); } }
3.什么是索引?
上面已经声明并且使用了索引,这里分析总结索引的概念和特征:
1).索引的概念
索引也是一种类成员,而且必须为实例成员,因为它就是为实例成员提供的一种访问方式,所以不能声明为static的。索引与属性类似,也有get访问器和set访问器。而且索引实际上就是一组get访问器和set访问器,而访问器的本质是方法,所以说,索引器的本质就是方法。索引器经常是在主要用于封装内部集合或数组的类型中声明的。
2).索引声明
索引声明使用下面的语法:
[访问修饰符] 返回值类型 this [ 参数1,参数2...]
{
get{......}
set{......}
}
语法要点:索引名称永远为this;索引的参数在方括号中间;索引的参数列表中至少有一个参数。
3).set访问器
当索引被用于赋值时,它的set访问器被隐式调用, set访问器的特征如下:
第一,它的返回值类型为void。
第二,它的参数列表和索引中声明的参数列表的相同。
第三,它有一个名为value的隐式值参数,参数类型和索引的类型相同。
4).get访问器
当索引被用于取值时,get访问器被隐式调用,get访问器的特征如下:
第一,它的返回值类型与索引类型相同。
第二,它的参数列表和索引中声明的参数列表的相同。
5).索引的安全性
在客户端代通过索引访问成员时,很可能发生索引越界等一些异常情况。有两种方式提高索引的安全性:
第一,为索引声明严格的访问级别控制,比如可以将set访问器的修饰符改为private。
// set访问器:赋值 private set { switch (index) { case 0: this.Chinese = value; break; case 1: this.Math = value; break; case 2: this.Englisth = value; break; default: // 索引越界时抛出异常 throw new ArgumentOutOfRangeException(); } }第二,检查成员的个数,或抛出异常。
1 // 索引越界时抛出异常2 throw new ArgumentOutOfRangeException();
6).索引重载
索引可以声明多个参数,也可以重载,索引重载只要参数列表不同就行了。下面为Course类声明几个索引的重载。
class Course { public float Chinese { set; get; } public float Math { set; get; } public float Englisth { set; get; } // 声明一个公开的float类型的索引器 public float this[int index] { // set访问器:赋值 set { switch (index) { case 0: this.Chinese = value; break; case 1: this.Math = value; break; case 2: this.Englisth = value; break; default: // 索引越界时抛出异常 throw new ArgumentOutOfRangeException(); } } // get访问器:取值 get { switch (index) { case 0: return this.Chinese; case 1: return this.Math; case 2: return this.Englisth; default: throw new ArgumentOutOfRangeException(); } } } // 索引重载 public float this[string name, float val] { set { switch (name) { case "Chinese": this.Chinese = value + val; break; case "Math": this.Math = value + val; break; case "English": this.Englisth = value + val; break; default: throw new ArgumentOutOfRangeException(); } } get { switch (name) { case "Chinese": return this.Chinese; case "Math": return this.Math; case "English": return this.Englisth; default: throw new ArgumentOutOfRangeException(); } } } // 重载2:只读索引 protected string this[int index, string name, bool flag] { set { } } }
三、索引器和属性的比较
1.相同点
1).索引和属性都不用分配内存位置来存储。
2).索引和属性都是为类的其它成员提供访问控制的。
3).索引和属性都有get访问器和set访问器,它们可以同时声明两个访问器,也可以只声明其中一个。
2.不同点
1).属性通常表示单独的数据成员,而索引表示多个数据成员。
2).属性既可以声明为实例属性,也可以声明为静态属性,而索引不能声明为静态的。
3).属性有简洁的自动实现属性,而索引必须声明完整。
4).get访问器:属性的 get 访问器没有参数,索引器的 get 访问器具有与索引器相同的形参表。
5).set访问器:属性的 set 访问器包含隐式 value 参数。除了值参数外,索引器的 set 访问器还具有与索引器相同的形参表。
- C#[1]this关键字和索引器
- this关键字,抽象类和索引器
- C#学习笔记--this关键字和索引器
- 构造器和this关键字
- this和super关键字(1)
- C++this关键字
- C++this 关键字
- this关键字和super关键字
- this关键字和static关键字
- this关键字和super关键字
- This关键字和Super关键字
- this关键字和super关键字
- 构造器、重载和this关键字
- 关键字base和this
- 关键字 - this 和base
- this和super关键字
- 关键字 this和base
- this 和 super关键字
- 编写高质量代码规范2
- Java中注解详解
- python 详解re模块
- 利众讲故事:攻下隔壁女生路由器后,我都做了些什么
- 引用计数法的循环引用问题
- C#[1]this关键字和索引器
- 实现点击音乐文件跳转到音乐播放器并自动播放音乐
- ABB RobotStudio(abb机器人仿真软件)下载 v6.0.2
- Java学习笔记(69)---------Lock
- Java堆和栈的区别
- 【第十二章】零配置 之 12.1 概述 ——跟我学spring3
- Android APP 应用分析
- hdu 1160 FatMouse's Speed dp
- 一起来学一点金融及投资常识,防止我们的财富被掠夺