编程笺言:“优良的设计不仅对使用过程隐去细节,也不允许数据成员被直接地访问。”
这一节,我们就看看索引器是如何将数组虚拟化了的......
一、属性
1.基本
(1)属性是字段意义上的扩充,使通过相同的语法访问;但属性不是变量,不是设计用来作为存储定位(storage location)使用,不可能把属性作为ref或out方式的参数传递;
(2)属性的语法为
[attributes] [modifiers] type [interface-type.]identifier {accessor-declaration}
(3)属性综合了字段和函数的特性,对象使用者可以象使用字段一样地使用属性;而要实现属性,必须使用最少一个代码块,最多两个代码块,以表示get访问器与/或(and/or)set访问器;
(4)属性数据的实际储存以“回存”(backing store)的方式进行,回存一般使用私有字段--以保证字段的属性,这一唯一的访问途径;
(5)属性有用于计算的读、写值的访问器(accessor);
(6)属性可以声明在接口上,称为接口属性;接口属性的访问器中不具有体,只需使用get;和set;关键字标明--该属性是否为读写、只读或只写即可;
(7)属性又叫无参属性,它是有参属性的变形,默认的参数是value值;
(8)属性有多项用途:
a/在允许变化之前,进行数据检验;
b/透明地公开类的数据,这些数据实际上是从其它的数据源如数据库检索而来的;
c/当更改数据时,采取对应措施,如激发某个事件或改变其它字段的值;
2.属性修饰符
(1)可使用四种访问修改器,public、private、protected、internal或protected internal;
(2)同一个属性的get、set访问器可以使用不同的修改器;
(3)静态(访问)的属性,表示该属性在任何时候都可访问;
(4)虚的属性,从派生类中--用override关键字重写属性行为,也可用sealed关键字来覆写;
(5)抽象的属性,不在该类中实现,但派生类必须实现;
(6)静态的属性,它的get、set访问器中不能使用virtual、abstract或override修饰符,否则会引起错误;
3.get访问器
(1)get访问器的主体类似于方法的格式;
(2)它必须返回属性声明的类型的值;
(3)它的执行等效于读取字段的值;例如,当从get访问器返回私有变量且能够进行优化(optimization are enabled)时,编译器负责内联(inline)调用get访问器的方法,但虚(virtual)get访问器方法除外,大体是编译器于编译时并不确定哪个方法会在运行时被调用。
(4)get访问器必须由return或throw语句中止,控制权不能转出到访问器主体之外;
(5)不建议使用get访问器来更改对象的状态(state of object),其本意是设计作返回字段值或计算且返回值使用;
//参考示例 class Employee { private string name; public string Name { get { return name != null ? name : "NA"; } } }
4.set访问器
(1)set访问器类似于无返回值(void)的方法;
(2)使用隐式参数value,value的类型与属性的类型相同;
(3)为属性赋值时,set访问器和带着新值的参数一起被调用;
(4)为set访问器的本地变量不能使用隐式参数名value,否则会引起错误;
//主要用途示例 public class Employee { private string name; public string Name { get { return name; } set { name = value; } } } public class Manager : Employee { private string name; // Notice the use of the new modifier: public new string Name { get { return name; } set { name = value + ", Manager"; } } } class TestHiding { static void Main() { Manager m1 = new Manager(); // Derived class property. m1.Name = "John"; // Base class property. ((Employee)m1).Name = "Mary"; System.Console.WriteLine("Name in the derived class is: {0}", m1.Name); System.Console.WriteLine("Name in the base class is: {0}", ((Employee)m1).Name); } } /* Output Name in the derived class is: John, Manager Name in the base class is: Mary */
//interface 属性示例 interface IEmployee { string Name { get; set; } int Counter { get; } } public class Employee : IEmployee { public static int numberOfEmployees; private string name; public string Name // read-write instance property { get { return name; } set { name = value; } } private int counter; public int Counter // read-only instance property { get { return counter; } } public Employee() // constructor { counter = ++counter + numberOfEmployees; } } class TestEmployee { static void Main() { System.Console.Write("Enter number of employees: "); Employee.numberOfEmployees = int.Parse(System.Console.ReadLine()); Employee e1 = new Employee(); System.Console.Write("Enter the name of the new employee: "); e1.Name = System.Console.ReadLine(); System.Console.WriteLine("The employee information:"); System.Console.WriteLine("Employee number: {0}", e1.Counter); System.Console.WriteLine("Employee name: {0}", e1.Name); } }
二、索引器(有参属性)
1.基本
(1)索引器提供了语法便利性,以便客户端程序能象数组一样地访问类、结构或接口的实例(请问,数组索引的是什么?答,数组元素;索引器索引的是什么?答,实例中的元素);
(2)索引器多用于以下这些类型中的实现:主要用于封装内部集合或数组的类型;
举例,一个名为TempRecord的类,记录24小时内10个时间的温度记录,浮点型数组"temps”记录温度,DateTime型数组保存了日期。在该类中实现索引器,以使客户端用--float temp = tr[4],而不是float temp = tr.temps[4]--来访问TempRecord实例中的温度。
(3)索引器符号使客户端程序的语法得到简化,同时使开发者更容易理解类的设计用途;
(4)索引器的语法为:
[attributes] [modifiers] type [interface-type.]this [formal-index-parameter-list] {accessor-declarations}
(5)索引器类型和它的参数类型,必须像索引器本身一样可访问;
(6)索引器签名是由形参的个数和类型组成,不包括(include)索引器类型或形参的名字;在一个类中声明的多个索引器,它扪的签名不能相同;
(7)索引器值不属于(classfied)变量,因此,不可能传递索引器值作为ref或out参数;
(8)要提供其它语言可以使用的索引器的名字,在声明中要使用name特性(attribute),如
//TheItem是索引器名字;不提供索引器名字,则缺省为Item [System.Runtime.CompilerServices.IndexerName("TheItem")] // Indexer declaration public int this [int index] { }
(9)索引器的索引类型不限于整数,可以使用其它如字符串等类型;使用字符串时,通过在集合中搜索来取得对应值;
2.建议采纳的编程风格:
(1)适当地增加错误处理,以避免客户端程序传递进来非法索引值;
(2)尽可能严格地限制get和set访问器的可访问性(accessibility),尤其是对set访问器。
3.接口中的索引器
(1)索引器可在接口上声明;它的语法为:
[attributes] [new] type this [formal-index-parameter-list] {interface-accessors}
(2)接口中索引器的访问器与类中索引器的访问器不同,表现为a/不使用修饰符 b/没有体;所以访问器的目的仅是用于指示读写、只读还是只写;
public interface ISomeInterface { //... // Indexer declaration: string this[int index] { get; set; } }
(3)同一接口中,索引器的签名不能相同;
//主要用途示例:索引器示例,通过该例可以清楚地看到索引器实现对集合或数组的操作 //故,在编译器内联后,索引器最终能够提供语法上的便利性 class TempRecord { // Array of temperature values private float[] temps = new float[10] { 56.2F, 56.7F, 56.5F, 56.9F, 58.8F, 61.3F, 65.9F, 62.1F, 59.2F, 57.5F }; // To enable client code to validate input when accessing your indexer. public int Length { get { return temps.Length; } } // Indexer declaration. // If index is out of range, the temps array will throw the exception. public float this[int index] { get { return temps[index]; } set { temps[index] = value; } } } class MainClass { static void Main() { TempRecord tempRecord = new TempRecord(); // Use the indexer's set accessor tempRecord[3] = 58.3F; tempRecord[5] = 60.1F; // Use the indexer's get accessor for (int i = 0; i < 10; i++) { System.Console.WriteLine("Element #{0} = {1}", i, tempRecord[i]); } // Keep the console window open in debug mode. System.Console.WriteLine("Press any key to exit."); System.Console.ReadKey(); } } /* Output: Element #0 = 56.2 Element #1 = 56.7 Element #2 = 56.5 Element #3 = 58.3 Element #4 = 58.8 Element #5 = 60.1 Element #6 = 65.9 Element #7 = 62.1 Element #8 = 59.2 Element #9 = 57.5 */
//主要用途示例:接口上的索引器示例 // Indexer on an interface: public interface ISomeInterface { // Indexer declaration: int this[int index] { get; set; } } // Implementing the interface. class IndexerClass : ISomeInterface { private int[] arr = new int[100]; public int this[int index] // indexer declaration { get { // The arr object will throw IndexOutOfRange exception. return arr[index]; } set { arr[index] = value; } } } class MainClass { static void Main() { IndexerClass test = new IndexerClass(); System.Random rand = new System.Random(); // Call the indexer to initialize its elements. for (int i = 0; i < 10; i++) { test[i] = rand.Next(); } for (int i = 0; i < 10; i++) { System.Console.WriteLine("Element #{0} = {1}", i, test[i]); } // Keep the console window open in debug mode. System.Console.WriteLine("Press any key to exit."); System.Console.ReadKey(); } } /* Sample output: Element #0 = 360877544 Element #1 = 327058047 Element #2 = 1913480832 Element #3 = 1519039937 Element #4 = 601472233 Element #5 = 323352310 Element #6 = 1422639981 Element #7 = 1797892494 Element #8 = 875761049 Element #9 = 393083859 */
小结:
(1)属性和索引器具有相似的地方,后者被称做带参数的属性;但索引器常用于对集合或数组的封闭类,来进行访问语法的简化;
(2)它们都可以用在接口中;
(3)索引器,简言之,即对集合的实例中的数组进行操作时,可以用"实例[n]"的简洁形式。换句话说,一种语法上封装!
发表评论
-
ZT,一篇好文
2010-05-03 10:33 999读读语言大牛们(其中有位是Anders)这篇文章,会很受益。( ... -
关于“匿名方法”与“lambda操作符”的实现
2010-03-24 22:29 871在<关于“回调”的实现>一文中,我们探讨了使用委托 ... -
effective hierarchy(二)之 函数合辑(2)
2009-09-16 21:29 727介绍: 本节我们来看看另外一种封装,构建件。构建件作为 ... -
effective hierarchy(二)之 函数合辑(1)
2009-08-19 14:53 781“暴露”阶段:值-> ... -
effective hierarchy(一)之 基本概念(8)
2009-07-02 23:39 685MSDN,C#2 一、语句 1.结束点和可达性(en ... -
effective hierarchy(一)之 基本概念结束篇
2009-06-30 15:41 662一、函数/功能成员(fun ... -
effective hierarchy(一)之 基本概念(7)
2009-06-23 21:15 936以下可跳过: [立记保留:到现在为止,我满意的是认真的精神。 ... -
effective hierarchy(一)之 基本概念(6)
2009-06-21 00:34 949MSDN,C#2.0 转换(conversions) ... -
effective hierarchy(一)之 基本概念(5)
2009-06-18 22:16 714MSDN,C#2.0 变量基本点: 变量代表 ... -
effective hierarchy(一)之 基本概念(4)
2009-06-15 15:59 726MSDN,C#2.0: 一、名字空间和类型名称(nam ... -
effective hierarchy(一)之 基本概念(3)
2009-06-14 15:00 729MSDN,C#2.0: 一、签 ... -
effective hierarchy(一)之 基本概念(2)
2009-06-13 18:22 827MSDN:基本概念 一、 ... -
effective hierarchy(一) 之基本概念(1)
2009-06-11 09:37 778我告诫自己,不要忽略简单的东西,又要扎实。所以这一篇开始,专门 ... -
effective hierarchy(一)之 从array说起(4)
2009-06-07 00:53 803回顾:上一节中,我们 ... -
effective hierarchy(一)之 从array说起(3)
2009-06-06 21:20 700回顾: 从上一节中,可以看出枚举的易用性对数组使用的启示意义 ... -
effective hierarchy(一)之 从array说起(2)
2009-06-06 09:34 691复习: 从上一节,可 ... -
effective hierarchy(一)之 从array说起(1)
2009-05-29 13:59 891MSDN(c#2.0): 数组的元义是 ... -
effective hierarchy(一)之 C#中的new
2009-05-27 23:21 840MSDN(c#2.0): 在msdn中,指出new的三种用法。 ...
相关推荐
Hierarchy Viewer是Android SDK中自带的一款强大的UI设计与检测工具。它位于Android SDK的`tools`目录下,文件名为`hierarchyviewer.bat`。对于Android开发者来说,这是一个不可或缺的工具,能够帮助他们在开发过程...
4. **自定义预览**:可能支持自定义游戏对象预览,使开发者能在Hierarchy面板中快速了解对象的状态和属性。 5. **快捷菜单**:增加自定义快捷菜单,使得常用操作触手可及,减少鼠标移动和点击次数,提高开发速度。 ...
Android 开发中,UI 分析工具 Hierarchy Viewer 是一个非常有用的工具,可以帮助开发者快速、方便地设计、调试和调整界面,提高用户的开发效率。本文将详细介绍如何使用 Hierarchy Viewer 工具在 Android 开发过程中...
本篇文档将详细介绍如何为员工及其部门经理创建一个层次数据源(Hierarchy Extractor)。通过这个层次数据源,管理者可以方便地获取到他们直接下属的信息以及这些下属所负责或有权访问的数据。此文档适用于运行ECC 5.0...
解决这个启动 View Hierarchy时的这个bug: hierarchy viewer unable to debug device
Unity是世界上最受欢迎的游戏开发引擎之一,它提供了丰富的工具和功能,让开发者能够创建高质量的2D和3D游戏。在Unity中,"层级编辑器"(Hierarchy)是至关重要的一个部分,它允许开发者组织和管理场景中的游戏对象...
Unity是世界上最流行的游戏开发引擎之一,它为开发者提供了丰富的工具集来创建交互式3D和2D内容。在Unity中,Hierarchy面板是一个至关重要的组成部分,它显示了场景中的所有游戏对象及其层次结构。QHierarchy是一款...
Hierarchy Viewer采用了经典的模型-视图-控制器(MVC)架构,以实现界面与数据处理的分离。具体而言: - **Controller**:`HierarchyViewerDirector.java`负责协调应用的逻辑流程,接收用户输入并作出响应。 - **...
效果及使用方法:https://blog.csdn.net/qq_26318597/article/details/131373576 1.导入插件包 2.选中Hierarchy中的物体 3.右键选择“复制Hierarchy路径” 4.Ctrl + V 粘贴
最后,我们可以使用3DTILES_batch_table_hierarchy扩展,来分组存储属性,相同的属性放在class里面,减少batchTable的字节大小。 我们可以通过增加属性信息来丰富BIM模型在3DTiles瓦片中的表现,并提高模型的可读性...
IRQ Hierarchy 的初始化及构建过程详解 IRQ(Interrupt Request)是计算机系统...IRQ hierarchy 的初始化及构建过程是一个复杂的过程,涉及到多个函数和数据结构。理解这些函数和数据结构对于系统的正确运行至关重要。
Enhanced_Hierarchy_2.0_v2.4.5.unitypackage 最新版本哦 正版
Hierarchy PRO 2021 v2021.1u9
Hierarchy PRO Presets And Selections v20.6层级编辑器强化工具最新版,对层级编辑器进行最大化的强化,很多功能,帮助编辑游戏对象,很多提示信息,可以选择要显示的内容,对开发帮助很大。
在这个名为“前端项目-d3-hierarchy.zip”的压缩包中,包含了一个使用D3.js库实现的层次数据可视化布局算法。D3.js(Data-Driven Documents)是一个强大的JavaScript库,专为创建动态、交互式的SVG、Canvas或WebGL...
本篇文章将基于“MFC_Hierarchy_Chart_V9.0”的内容,对MFC中的类层次结构进行详细的分析与解释,帮助读者更好地理解这些类之间的关系以及如何在实际项目中应用它们。 #### MFC类层次结构概述 MFC类层次结构以`...
WPF Class Hierarchy
总结来说,HierarchyViewer是Android开发者必备的工具之一,它提供了对应用界面进行深入分析和优化的能力。熟练掌握并运用HierarchyViewer,不仅能够提升应用的性能,还能让用户体验更上一层楼。在实际开发中,我们...
Hierarchy2 v1.3.10.0