对象和类型:
内容:
1.类和结构的区别
2.类成员
3.按值和按引用传送参数
4.访求重载
5.构造函数和静态构造函数
6.只读字段
7.部分类
8.静态类
9.Object类,其他类型都从该类派生而来。
一、类和结构
类和结构实际上都是创建对象的模板,每个对象都包含数据,并提供了处理和访问数据的方法。类定义了类的每个对象或称为实例,可以包含什么数据和功能。还可以定义处理在这些字段中存储的数据的功能。结构与类的区别是他们在内存中的存储方式,访问方式和他们的一些特征(如结构不支持继承)。类是存储在堆上的引用类型,而结构是存储在栈上的值类型。较小的数据类型使用结构可提高性能。但在语法上,结构与类非常相信。他们的区别是使用关键字Struct,代替Class来声明结构。都可以用New 来声明实例。这个关键字用来创建对象并对其进行初始化。
二、类
类中的数据和函数称为类的成员,除了这些成员外,类还可以包含嵌套的类型。成员的可访问性是:public,protected,internal protected,private 和internal
1.数据成员:是包含类的数据:字段,常量和事件的成员。数据成员可以是静态数据。类成员总是实例成员,除非用static进行显式声明。
字段是与类相关的变量。常量与类的关联方式同变量与类的关联方式。 使 用 const关 键字来声明常量。如果把它声明为public ,就 可以 在类的 外部访问 它。
事件是类的成员,在发生某些行为时它可以让对象通知调用方。客户可以包含所谓“事件处理程序”的代码来响应该事件。
2.函数成员
函数成员提供了操作类中数据的某些功能,包括方法,属性,构造函数和终结器、运算符及索引器。
1) 方法是某个类相关的函数,与数据成员一样,函数成员默认为实例成员。除非用static修饰为静态
2) 属性是可以从客户端访问的函数组,其访问方式与访问类的公共字段类似。C#为读写类中的属性提供了专用语法,所以不必使用那些名称中嵌有Get或Set的方法。因为属性的这种语法不同于一般函数的语法,在客户端代码中,虚拟的对象被当做实际的东西。
3) 构造函数是在实例化对象进自动调用的特殊函数,它们必须与所属的类同名,且不能包含返回类型,Void也不可以。构造函数用于初始化字段的值。
4) 终结器类似于构造函数,但是在CLR检测到不再需要某个对象时调用它。他们的名称也类相同,但前面有一个~符号。不可能预测什么时候调用终结器。
5) 运算符执行的最简单的操作就是加法和减法。在两个整数相加时,严格地说,就是对整数使用+运算符。C#还允许指定把已有的运算符应用于自己的类(运算符重载)。
6) 索引器允许以数组或集合的方式进行索引。
(一)方法:
正式的C#术语区分函 数和方法。 在 C#术 语中,“函 数成员”不仅包含方法,而 且也包含类或结构的一些非数据成员,如索引器、 运算符、构造函 数和析构函 数等,甚至还有属性。 这些都不是数据成员,字段、常量和事件才是数据成员。
方法的声明:[修饰符] 返回值类型 方法名([参数列表]){}
方法的调用:实例方法,静态方法,有参数/无参数,有返回值/无返回值
值参数传递,引用参数传递,ref参数(须初始化),out参数
参数命名,指定参数赋值,可选参数
方法的重载:两个方法不能仅在返回 类型上有区 别。两个方法不能仅根据参数是声明为 ref还 是 out来 区分
(二) 属性
它 是一个方法或一对方法,在 客户端代码看来,它/它们是一个字段。
属性访问器:get,set。get访问器不带任何参数,且必须返回属性声明的类型。也不应为 set访问器指定任何显式参数,但编译器假定它带一个参数,其类型也与属性相同,表示 value。只有get或set属性问题器,可改变属性的可访问性,如只读属性没有set访问器,只写属性没有get访问器。不过不支持如此定义。属性的get、set访问器可以有不同的修饰符。在 get和 set访问 器中,必 须有一个具备属性的 访问 级别。 如果 get访 问 器的 访问 级别是protected,就 会产生一个编译错误,因 为这会使两个访问器的 访问 级别都不是属性。
自 动实现的 属性:如果属性的 set和 get访 问 器中 没有任何逻辑,就可以 使 用 自 动实现的属性{get;set;}必须两个都存在 。
内联代码:在 何处 内 联代码完全 由 CLR决 定。。JIT 编译器可生成高度优化的代码,并在适当的时候随意地内联代码。
三、构造函数
定义,无返回类型,初始化,默认,重载
定义私有构造函数:则不能在外部代码中实例化类,但可以在内部编写一个公有静态属性或方法以实例化该类。一般用于,类仅用作某些静态成员或属性的窗口,因此永远不会实例化它,或希望类仅通过调用某个静态成员函数来实例化,即所谓对象实例化的工厂方法。
定义静态构造函数:这种构造函数只执行一次,只要创建类的对象就会执行它。作用是:类有一些静态字段或属性,需要在第一闪使用类之前,从外部源中初始化这些静态字段和属性。C#中,通常在第一次调用类的任何成员之前执行静态构造函数。静态构造函数没有访问修饰符,同.net运行库调用,且不能带任何参数。一个类只能有一个静态构造函数。类的静态构造函数只能访问类的静态成员,不能访问类的实例成员。可以与无参实例构造函数同时存在。
在构造函数中调用其他构造函数:构造函数初始化器:在一个构造函数)结束{未开始的地方,用this(参数列表)来调用,此方法也可用于基类,用base代替this
只读字段:常量的概念是一个包含不能修改的值的变量,关键字是const,声明时即赋初值。只读字段readonly,允许把一个字段设置为常量,但还需要执行一些计算,才能确定它的初始值。规则是可以在构造函数中给只读字段赋值,不能在其他地方赋值。Const默认是静态?readonly默认是实例字段,如果想设置为静态,须显示声明。
(四)匿名类型:var 与new 关键字一起使用。匿名类型只是一个继承 自Object且没有名称的 类。 该类的 定义从初始化器中 推断,类似于隐 式类型化的 变量。这些新对象的类型名未知,编译器为类型伪造了一个名称,但只有编译器才能使用它们,不能也不应使用新对象上的任何类型反射,因为这不会得到一致的结果。
四、结构
结构是值类型,不是引用类型。它们存储在栈中 或存储为内 联(inline)如果它们是存储在堆中的另一个对象的一部分,其生存期的限制与简单的数据类型一样。
- 结构不支持继承。
- 对于结构构造函数的工作方式有一些区别。尤其是编译器总是提供一个无参数的默认构造函 数,它 是不允许替换的。
- 使用结构,可 以 指定字段如何在内存中的 布局
1.结构是值类型,不是引用类型
因为结构实际上是把数据项组合在一起,有 时大多数或者全部字段都声明为public。 严格来说,这与编写.NET代码的规则相反——根据 Microsoft,字 段(除了const字段之外)应 总是私有的,并 由公有属性封装。 但是,对于简单的结构,许多开发人员都认为公有字段是可接受的编程方式。
结构是值类型,但语法上常常可以把它们当作类来处理,如可以用new关键字来新建对象并初始化,因 为结构是值类型,所以11ew运 算符与类和其他引用类型的工作方式不同。 new运 算符并不分配堆中的内 存,而是只调用相应的构造函数,根据传送给它的参数,初始化所有的字段。结构遵循其他数据类型都遵循的规则:在使用前所有的元素都必须进行初始化。在结构上调用new运 算符,或 者给所有的字段分别赋值,结 构就完全初始化了。当然,如 果结构定义为类的成员字段,在 初始化包含的对象时,该结构会 自 动初始化为 0。结构是会影响性能的值类型,但根据使用结构的方式,这种影响可能是正面的,也 可能是负面的。结构主要用于小的 数据结构。把结构作为参数传递给方法时,应把它作为 ref参 数传递,以 避免性能损失,但如果这 样做,就 必须注意被调用的方法可以改变结构的 值。
2.结构和继承
结构不是为继承设计的,即它不能从一个结构中继承。唯一的例外是对应的结构最终派生于类System.Object。因此结构可以访问Object的方法,甚至重写Object的方法 。每个结构派生自System.ValueType,System.ValueType类又派生自System.Object。ValueType并没有为Object添加任何新成员,但提供了一些更适合结构的实现方式。注意,不能为结构提供其他其类,每个结构都派生自ValueType。
3.结构的构造函数
不允许定义无参构造函数。系统默认提供这个无参构造函数,并不允许覆盖或重新定义。默认构造函数把数值字段初始化为0,引用类型字段初始化为Null,所以在定义结构时给字段赋初始值是不允许的。另外,可以 像类那样为结构提供 Close()或 Dispose()方法
五、部分类
partial关键字允许把类、结构或接口放在多个文件中。partial关键字放在class,struct,interface关键字的前面。如果声明类时 使 用了 下 面的 关键字,这 些关 键字就必须应 用于同 一个 类的 所有部分:public ,private,protected,internal,abstract,sealed,new ,一般约束。在嵌套的 类型中,只 要 卩 蚯Ⅲ 关键子位于 class关 键字的 前面:就 岢以 嵌套部分类:在 把部分类编译到 类型中时,属 性、XML 注释、 接 口、 泛型类型的参数属性和成员会合并。
六、静态类
如果一个类只包含静态的方法和属性,该类就是静态的。static关键字在class关键字前面,即表示。静态类在功能上与使用私有静态构造函数创建的类相同。不能创建静态类的实例。使用static关键字,编译骂可以检查用户是否不经意间给该类添加了实例成员。如果是,就生成一个编译错误,这可以确保不创建静态类的实例。
七、Object类
所有类默认派生自或间接派生自Object类。结构总是派生自ValueType类
- · ToString()方法:是获取对象的 字符串 表示的 一种便捷方式。 当 只需要快速获取对象的内容,以 进行调试时,就 可以 使 用这个方法。 在数据的 格式化方面,它 几乎没有提供选择:例 如,在原则上日 期可以 表示为许多不同的 格式,但DateTime.ToString()没有在这方面提供任何选择。如果需要更复杂的 字符串 表示,例如,考 虑用户的 格式化首选项或 文化(区域)就应实 现IFormattable接口。
- ●GetHashTable()方 法:如 果对象放在名为映射(也 称为散列表或字典)的 数据结构中,就可以使用这个方法。处理这些结构的 类使 用该方法确定把对象放在结构的 什么地方。 如果希望把类用作字典的一个键,就需要重写GetHashTable()方法。 实现该方法重载的方式有一些相当严格的限制。
- ● Equals()( 两个版本)和 ReferenceEqualsO方 法:如 果把 3个 用于比较对象相等性的 不同 方法组合起来,就 说明.NET Framework在 比 较相等性方面有相当复杂的 模式。 这 3个方法和比 较运算符“==” 在使 用方式上有微妙的区别。而且,在重写带一个参数的 虚Equals()方 法时也有一些限 制,因 为System.Collections名称空间中的一些基类要调用该方法,并希望它以 特定的方式执行。
- ● Finalize()方法:它最接近 C++的 析构函 数,在 引 用对象作为垃圾被回收以 清理资源时调用它。 Object中的实 现方式实际上什么也没有做,因 而被垃圾收集器忽略。 如果对象拥有对未托管资源的引 用,则 在该 对象被删除时,就 需要删除这些引用,此时一般要重写。 垃圾收 集器不能直接删除这些对未托管资 源的引用,因 为它只负责托管的资源,于是它只能依赖用户提供的Finalize()。
- ● GetType()方 法:这个方法返回从 system.Type派 生的 类的一个实例。 这个对象可以提供对象成员所属类的更多 信息,包括基本类型、方法、属性等。System.Type还 提供了.NET的反射技术的入口 点。
- ● MemberwiseClone()方 法:这 是System.Object中 唯一没有在本书的 其他地方详细论述的方法。不需要讨论这个方法,因 为它在概念上相当简单,它只复制对象,并 返回对副本的一个引用(对 于值类型,就是一 个装箱的引 用)。 注意,得到的 副本是一个浅表复制,即它复制了 类中的所有值类型。如果类包含内 嵌的引用,就 只复制引 用,而 不复制引用的 对象。 这个方法是受保护的,所 以 不能用于复制外部的 对象。该方法不是虚方法,所以 不能重写它的实现代码。
ToString()方法的重写
八、扩展方法