第三章 对象和类型

本章的内容:

类和结构的区别

类成员

按值和按引用传送参数

方法重载

构造函数和静态构造函数

只读字段

部分类

静态类

Object类,其他类型都从该类派生而来

3.1 类和结构

类和结构都是创建对象的模板,每个对象都包含数据,并提供了处理和访问数据的方法

结构和类的区别是他们在内存中的存储方式、访问方式(类是存储在堆上的引用类型,而结构是存储在栈上的值类型)和他们的一些特征(如结构不支持继承)。较小的数据类型使用结构可提高性能。但在语法上,结构和类非常相似,主要的区别是使用关键字struct代替class来声明结构。

对于类和机构,都使用关键字new来声明实例。

3.2 类

3.2.1 数据成员

类中的数据和函数称为类的成员。数据成员和函数成员

成员的可访问性:public、protected、internal protected、private或internal

数据成员:字段、常量和事件

使用const关键字来声明常量。

函数成员提供了操作类中数据的某些功能,包括方法、属性、构造函数和终结器(finalizer)、运算符及其索引器

3.2.2 函数成员

构造函数是实例化对象时自动调用的特殊函数。他们必须与所属的类同名,且不能有返回类型。构造函数用于初始化字段的值

终结器类似于构造函数,但是在CLR检测到不再需要某个对象时调用它。它们的名称与类相同,但前面有个“~”符号

索引器允许对象以数组或集合的方式进行索引

如果把一个参数传递给方法,且这个方法的输入参数前带有ref关键字,则方法对变量所做的任何改变都会影响原始对象的值

c#要求对传递给方法的参数进行初始化,在传递给方法之前,无论是按值传递,还是按引用传递,任何变量都必须初始化。

带有out关键字的变量可以不用初始化

参数也可以是可选的,必须为可选参数提供默认值。可选参数还必须是方法定义的最后一个参数。

c#支持方法的重载-----方法的几个版本有不同的签名(即,方法名相同,但参数的个数和/或类型不同)。为了重载方法,只需声明同名但参数或类型不同的方法即可。

c#的一个新特征是也可以给类编写无参数的静态构造函数。这种构造函数只运行一次,而前面的构造函数是实例构造函数,只要创建类的对象,就会执行它们。

编写静态构造函数的一个原因是,类有一些静态字段或属性,需要在第一次使用类之前,从外部源中初始化这些静态字段和属性。

静态构造函数没有访问修饰符,其他c#代码从来不调用它,但在加载类时,总是由.NET运行库调用它,所以像public或private这样的访问修饰符就没有任何意义。出于同样原因,静态构造函数不能带任何参数,一个类也只能有一个静态构造函数。很显然,静态构造函数只能访问类的静态成员,不能访问类的实例成员。

注意,无参数的实例构造函数与静态构造函数可以在同一个类中同时定义。尽管参数列表相同,但这并不矛盾,因为在加载类时执行静态构造函数,而在创建实例时执行实例构造函数,所以何时执行哪个构造函数不会有冲突。

public class UserPreference

{

public static readonly Color BackColor;

static UserPreference()

{

DateTime now = DateTime.Now;

if ( now.DayOfWeek == DayOfWeek.Saturday)

{

BackColor = Color.Green;

}

else

{

BackColor = Color.Red;

}

}

}

从构造函数中调用其他构造函数

class Car

{

private string description;

orivate uint nWheels;

public Car(string description, uint nWheels)

{

this.description = description;

this.nWheels = nWheels;

}

public Car(string description):this(description,4)

{}

}

3.2.3 只读字段

只读字段只能在构造函数中给其赋值,不能再其他地方赋值。只读字段还可以是一个实例字段,而不是静态字段,类的每个实例可以有不同的值。与const字段不同,如果要把只读字段设置为静态,就必须显示声明它

3.3 匿名类型

匿名类型只是一个继承自Object且没有名称的类。

var captain = new {person.FirstName, person.MiddleName, person.LastName};

3.4 结构

结构是值类型,不是引用类型。它们存储在栈中或存储为内联(inline)(如果它们是存储在堆中的另一个对象的一部分),其生存期的限制与简单的数据类型一样。

结构不支持继承

对于结构构造函数的工作方式有一些区别。尤其是编译器总是提供一个无参数的默认构造函数,他是不允许替换的。

使用结构可以指定字段在如何在内存中的布局

3.4.1 结构是值类型

虽然结构是值类型,单在语法上常常可以把他们当做类来处理。

注意:因为结构是值类型,所以new运算符与其他引用类型的工作方式不同。new运算符并不分配堆中的内存,而是只调用相应的构造函数,根据传送给他的参数,初始化所有字段。对于结构。变量声明实际上是为整个结构在栈中分配空间。

结构遵循其他数据类型遵循的规则:在使用前所有的元素都必须进行初始化。在结构上用new运算符,或者给所有的字段分别赋值,结构就完全初始化了。

3.4.2 结构和继承

结构不是为继承设计的,这意味着:它不能从一个结构中继承。

3.4.3 结构的构造函数

为结构定义构造函数的方式与为类定义构造函数的方式相同,但不允许定义无参数的构造函数。

3.5 部分类

partial关键字运行把类、结构或接口放在多个文件中。

3.6 静态类

3.7 Object

所有的.NET类都派生自System.Object。实际上,如果在定义类时没有指定基类,编译器就会自动假定这个类派生自Object。结构总是派生自System.ValueType,System.ValueType又派生自System.Object

其实际意义在于,除了自己定义的方法和属性等外,还可以访问为Object定义的许多公有的和受保护的成员方法。这些方法可以用于自己定义的所有其他类中。

3.7.1 System.Object()方法

3.7.2 ToString()方法

如果不在自已定义的类中重写ToString(),该类只继承System.Object的实现。他显示类的名称。

3.8 扩展方法

扩展方法是静态方法,它是类的一部分,但实际上没有放在类的源代码中。假定Money类需要一个方法AddToAmount(decimal amountToAdd).但是,由于某种原因,程序最初的源代码不能直接修改,此时必须做的所有工作就是创建一个静态类,把方法AddToAmount()添加为一个静态方法。对应的代码如下:

namespace Wrox

{

public static class MoneyExtension

{

public static void AddToAmoumt(this Money money,decimal amountToAdd)

{

money.Amount += amountToAdd;

}

}

}

注意AddToAmount()方法的参数,对于扩展方法,第一个参数是要扩展的类型,它放在this关键字的后面。这告诉编译器,这个方法是Money类型的一部分。在扩展方法中,可以访问所扩展类型的所有公有方法和属性。

3.9 小结

c#高级编程第七版 学习笔记 第三章 对象和类型的更多相关文章

  1. c#高级编程第七版 学习笔记 第一章 .NET体系结构

    第一章      .NET体系结构 本章内容: 编译和运行面向.NET的代码 Microsoft中间语言(Microsoft Intermediate Language,MSIL或简称IL)的优点 值 ...

  2. c#高级编程第七版 学习笔记 第二章 核心c#

    第二章 核心C# 本章内容: 声明变量 变量的初始化和作用域 C#的预定义数据类型 在c#程序中使用条件语句.循环和跳转语句执行流 枚举 名称空间 Main()方法 基本的命令行c#编译器选项 使用S ...

  3. C#高级编程(第六版)学习:第三十一章:Windows窗体

    第三十一章 Windows窗体 创建Windows窗体应用程序 在文本编辑器中输入: /* * form.cs * a simple windows form * */ using System; u ...

  4. C++Primer第5版学习笔记(三)

    C++Primer第5版学习笔记(三) 第四/五章的重难点内容           你可以点击这里回顾第三章内容       因为第五章的内容比较少,因此和第四章的笔记内容合并.       第四章是 ...

  5. 《DOM Scripting》学习笔记-——第三章 DOM

    <Dom Scripting>学习笔记 第三章 DOM 本章内容: 1.节点的概念. 2.四个DOM方法:getElementById, getElementsByTagName, get ...

  6. The Road to learn React书籍学习笔记(第三章)

    The Road to learn React书籍学习笔记(第三章) 代码详情 声明周期方法 通过之前的学习,可以了解到ES6 类组件中的生命周期方法 constructor() 和 render() ...

  7. [HeadFrist-HTMLCSS学习笔记]第三章构建模块:Web页面建设

    [HeadFrist-HTMLCSS学习笔记]第三章构建模块:Web页面建设 敲黑板!! <q>元素添加短引用,<blockquote>添加长引用 在段落里添加引用就使用< ...

  8. JVM学习笔记-第三章-垃圾收集器与内存分配策略

    JVM学习笔记-第三章-垃圾收集器与内存分配策略 tips:对于3.4之前的章节可见博客:https://blog.csdn.net/sanhewuyang/article/details/95380 ...

  9. C#高级编程第9版 阅读笔记(一)

    一.前言 C# 简洁.类型安全的面向对象的语言. .NET是一种在windows平台上编程的架构——一种API. C#是一种从头开始设计的用于.NET的语言,他可以利用.NET Framework及其 ...

随机推荐

  1. BCP文件导入SQLServer数据库遇到的问题

    1. BCP文件插入sql server数据库,未指定数据库字段类型情况下,需要每个字段单独指定字段长度 2.文件中的存储值得类型 3.设置最大的类型

  2. 解决Office 2016客户端如何同SharePoint Server2016安装在一起

    前言 Microsoft Office 2016 客户端默认使用新式验证. 在某些配置中,新式验证不受安装有 SharePoint Server 2016 的 Office 2016 客户端的支持,例 ...

  3. linux如何添加telnet服务

    一.安装telnet 1.检测telnet-server的rpm包是否安装 [root@localhost ~]# rpm -qa telnet-server 若无输入内容,则表示没有安装.出于安全考 ...

  4. react 编写日历组件

    简单的日历组件 import React, { Component } from "react"; import * as _ from "lodash"; c ...

  5. 3.nodejs(三) 常用API

    1.querystring querystring: --- > qs npm i qs ==> qs:parse/stringify第三方插件,只有一个参数 JSON.parse  字符 ...

  6. 利用docker搭建ubuntu+nginx+PHP容器

      环境:操作系统(Ubuntu  16.04 64位); php7.1;  nginx/1.14.0   基础环境准备: 整体思路:docker pull一个ubuntu镜像,然后在容器中安装ngi ...

  7. kill、killall、pkill杀手三人组

    1.1 kill.killall.pkill杀手三人组 1.利用kill 进程号 方式杀掉rsync进程 [root@backup ~]# ps -ef |grep rsync root 3500 1 ...

  8. 剑指offer——python【第44题】翻转单词顺序

    题目描述 牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上.同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思.例如,“student ...

  9. day16:内置函数二

    1,大作业,yield 返回之后可以对数据进行处理了就,注意函数的解耦,每一个小功能写成一个函数,增强可读性,写之前自己要先把整体功能分块,先做什么,在做什么 # 现在需要对这个员工信息文件进行增删改 ...

  10. VMware Workstation下ubuntu虚拟机无法上网连不上网络解决

    写在前面:本博客为本人原创,严禁任何形式的转载!本博客只允许放在博客园(.cnblogs.com),如果您在其他网站看到这篇博文,请通过下面这个唯一的合法链接转到原文! 本博客全网唯一合法URL:ht ...