【C#】第2章学习要点

时间:2023-03-08 17:12:11
【C#】第2章学习要点

分类:C#、VS2015

创建日期:2016-06-15

教材:(十二五*规划教材)《C#程序设计及应用教程》(第3版)

一、本章要点

C#数据类型分两大类:值类型、引用类型。

值类型:栈(Stack)中保存的就是数据的值。

引用类型:栈中保存的是堆(Heap)中对象的引用地址。

栈(Stack)、堆(Heap)本质上都是在内存中开辟的区域,栈和堆都是由.NET框架统一对其进行管理,这样可防止直接把内存交给不合格的程序员写的乱七八糟的程序,而导致内存泄漏等问题。

二、值类型

值类型包括:简单类型、枚举类型、结构类型、可空类型。

值类型的特点:栈中保存的就是数据的值。

1、简单类型

简单类型又分为整型、浮点型、布尔型、字符型。

(1)整型

共8种。

sbyte:代表有符号的8位二进制整数(1字节),十进制数值范围从-128~127。

byte:代表无符号的8位二进制整数(1字节),十进制数值范围从0~255。

short:代表有符号的16位二进制整数(2字节),十进制范围从-32768~32767。

ushort:代表无符号的16位二进制整数(2字节),十进制范围从0~65535。

int:代表有符号的32位二进制整数(4字节),十进制范围从-2147483648~2147483648。

uint:代表无符号的32位二进制整数(4字节),十进制范围从0~4294967295,类型指定符为U。

long:代表有符号的64位二进制整数(8字节),十进制范围从-9223372036854775808~9223372036854775808,类型指定符为L。

ulong:代表无符号的64位二进制整数(8字节),十进制范围从0~18446744073709551615,类型指定符为UL。

例如:

int a =1234;

long x = 1234L;

long y = 1234; //int型的数值1234隐式地转换为long类型

long z = 0x12ab; //声明一个长整型变量x,并为其赋值为十六进制的数据12ABH

(2)浮点型

有3种。

float:32位(4字节)IEEE单精度浮点数,精度为十进制小数点后7位,取值范围1.5*10^-45~3.4*10^38,类型指定符为F

double:64位(8字节)IEEE双精度浮点数,精度为十进制小数点后15~16位,取值范围5.0*10^-324~1.7*10^308,类型指定符为E

decimal:128位(16字节)高精度浮点数,精度为十进制28~29位,取值范围1.0*10^-28~7.9*10^28,类型指定符为M。

例如:

float x=2.3F; //x=2.3

double y=2.7E+23; //y=2.7*10^23

decimal myMoney =300.5M;

decimal y =9999999999999999999999999M;

decimal x =123.123456789M;

(3)布尔型

只有两种可能的值:true、false。

例如:

bool isMale = false;

bool b = (i>0 && i<10);

(4)字符型

用char表示,表示单个Unicode字符,一个Unicode字符的长度为1(占两个字节)。

例如:

char c1='A';

char c2='\x0041'; //字母“A”的十六进制表示

char c3='\u0041'; //字母“A”的Unicode表示

2、枚举类型

在C#中,枚举类型(简称枚举)表示一组命名常量。

(1)定义

定义枚举类型时,所有常量共同使用一种基本类型(8中整型中的任何一种整型),如果基本类型不是int,需要用冒号来指定是哪种基本类型。

例如:

using System;

namespace ConsoleApplication1

{

enum Days{Sun,Mon,Tue}; //Sun:0,Mon:1,Tue:2

enum Numbers:byte{x1=3,x2=5};

classClass1

{

Days day=Days.Sun;

}

}

(2)常用方法

获取枚举类型中定义的所有符号名称:

string[] dayNames = Enum.GetNames(typeof(Days));

获取枚举类型中定义的所有符号名称对应的数值

int[] dayIndex = (int[])Enum.GetValues(typeof(Days));

3、结构类型

.NET框架已经预定义了一些结构,比如System.DateTime等。除此之外,你还可以自定义结构,关键字为struct。

struct是一种轻量型的class。

凡是用struct实现的,也都可以用class实现。如果你刚开始搞不清到底用哪种比较好,就先用class实现吧。等你做实际项目时,你会慢慢理解有些情况下将某些class改为用struct去实现会显著提升执行的效率。

4、可空类型

即:可以为null的值类型,它实际是泛型Nullable<T>的缩写。比如数据库中某条记录中的年龄字段可能是个整数也可能是null。当你将这个字段赋值给一个age变量时,age本质上就是“可以为null”的值类型。

例如:

Nullable<int> x=5;

Nullable<double> y=3.4;

这两条语句的另一种写法是:

int? x=5;

double? y=3.4;

两种写法的功能完全相同。

三、引用类型

包括:字符串类型(string,简称字符串)、类类型(class,简称类)、接口类型(interface,简称接口)、数组类型(array,简称数组)和委托类型(delegate,简称委托)。

1、字符串

string表示一连串UniCode编码的字符。

例如:

string str1="ABCD";

2、数组

常用的是一维、二维。

一维:

int[] a={1,2,3};

二维:

int[,] b=

{

{1,2,3},

{4,5,6}

}

3、类

.NET框架已经给你提供了上万个类,你可以直接用它们编写各种逻辑代码。除此之外,你还可以自己定义class。

类的本质含义:就是把乱七八糟搅和在一起的东西分分类,并用代码给它描述出来。比如苹果、梨、枣、柿子都搅和在一块,如果你希望把他们区分出来分别进行处理,那就得先把他们分类。

抽象:把苹果、梨、枣、柿子共有的东西抽取出来(比如都有水),然后用一个单独的名字去描述这个类,就是抽象。当然,如果抽取不合理,抽取出来的也可能是个四不像,呵呵。

后面会专门用一章来介绍它。

4、接口

接口的本质含义:甲和乙约定,甲负责买电视、冰箱,乙负责买家具、锅碗瓢盆。这就是甲和乙之间声明的接口。但是谁去买、买什么型号等都没有说,即:接口仅有声明部分,没有实现部分。

如果甲安排丙去买电视,安排丁去买冰箱,那就是甲的具体实现由丙和丁去完成,不一定是甲亲自去买。

.NET框架已经提供了很多接口的定义和实现,你可以直接用它们编写各种逻辑代码。除此之外,你还可以自己定义interface。

后面会专门用一章来介绍它。

5、委托

是对指针的封装,这样可避免没有经验的程序员把内存搞的乱糟糟。

后面会专门用一章来介绍它。

6、事件

利用事件可快速响应用户的操作(鼠标、键盘、触摸、滑动等)。

事件是利用委托来实现的。

四、数据类型之间的转换

1、值类型与值类型之间的转换

(1)隐式转换

范围小的转换为范围大的:肯定没问题,比如将int(占4个字节)类型的数转换为用long(8个字节)类型存储,由于肯定没问题,所以编译器就直接去做了,不需要你告诉它。例如:

int a =15;

long b=a;

(2)显式转换

范围大的转换为范围小的:必须显式告诉编译器你就想这样干,不用考虑是不是有丢数据的问题。例如:

long b=12345;

int a=(int)b;

(3)用Convert()方法实现

也可以用System命名空间下的.Convert(...)方法进行转换。对于某些特殊情况,用该方法转换很是很方便的。

2、引用类型与引用类型之间的转换

假如B类继承自A类,即B是A的孩子:

class A{...}

class B:A{...}

另外,又假如有下面的代码:

A a=new A();

B b=new B();

那么,也可以这样写(隐式转换):

A b =new B();

3、值类型和引用类型之间的转换

在.NET框架中,值类型和引用类型之间的转换是靠“装箱”和“拆箱”来实现的。

4、字符串和数值之间的转换

(1)字符串转换为数值

常用有:

int.Parse(...)、int.TryParse(...)

double.Parse(...)、double.TryParse(...)

(2)数值转换为字符串

常用有:

string.Format(...)或者$前缀

ToString()

五、运算符

1、基本运算符

和C++相同。

2、is和as运算符

is运算符用于检查对象是否与给定类型兼容。例如:

if (obj is MyObject)

{

//......

}

如果所提供的表达式非空,并且所提供的对象可以强制转换为所提供的类型而不会导致引发异常,则is表达式的计算结果将是true。注意is运算符只考虑引用转换、装箱转换和取消装箱转换。不考虑其他转换(如用户定义的转换)。

as运算符类似于强制转换操作,如果转换失败返回null但不引发异常。

3、typeof

用于获取类型的 System.Type 对象。例如:

System.Type type = typeof(int);

上面这条语句也可以用下面的办法实现:

int i = 0;

System.Type type = i.GetType();

4、其他运算符

其他运算符后面的章节还会涉及到,用到时再说。

六、表达式

1、基本运算符和表达式

和C++相同。

2、LINQ查询表达式

后面章节中再单独介绍。

3、Lambda表达式

后面章节中再单独介绍。

七、流程控制语句

C#的流程控制语句都是程序指令。除非有特别说明,语句都按顺序执行。

1、基本语句

C#具有下列基本语句:

(1)分支语句:if-else,switch

(2)循环语句:while,do-while,for,foreach

(3)跳转语句:break,continue,goto,return

(4)异常处理语句:throw,try-catch,try-catch-finally,try-finally

2、using语句

提供了能确保正确使用IDisposable对象的方便语法。例如:

using (Font font1 = new Font("Arial", 10.0f), font2 = new Font("Arial", 10.0f))

{

// 使用 font1 和 font2

}

3、其他语句(了解)

下面这些都是在特殊场合下使用的语句,教材中没有涉及这方面的内容。

(2)yield return; yield break;

含义及用法见:https://msdn.microsoft.com/zh-cn/library/9k7k7cf0.aspx

(3)checked, unchecked

含义及用法见:https://msdn.microsoft.com/zh-cn/library/khy08726.aspx

(4)fixed

含义及用法见:https://msdn.microsoft.com/zh-cn/library/f58wzh21.aspx

(5)lock

含义及用法见:https://msdn.microsoft.com/zh-cn/library/c5kehkcz.aspx

八*、不安全代码和指针(了解)

为了保持类型安全,C#默认情况下不支持指针。不过,如果你希望使用指针来控制缓冲区,通过使用unsafe关键字也可以定义可使用指针的不安全上下文。

教材没有涉及这方面的内容。如果你希望了解这方面的详细信息,请参考:

https://msdn.microsoft.com/zh-cn/library/t2yzs44b.aspx