1.值类型和引用类型
根据在内存中存储位置的不同,C#中的数据类型可分为两类:值类型和引用类型。
值类型:该类型的数据长度固定,存放于堆栈(stack)上。值类型变量直接保存变量的值,一旦离开其定义的作用域,立即就会从内存中删除。
引用类型:该类型数据的长度可变,存放于堆(Heap)上。引用类型变量保存的是数据的引用地址,并一直被保留在内存中,直到.NET垃圾回收器将它们销毁。
2.
作为完全面向对象的语言,C#中的数据类型是统一的,任何类型都是直接或间接的从object类型派生来的,任何类型的值都可以被当作对象。
3.
C#是个强类型的安全语言,编译器要对所有变量的数据类型作严格的检查,保证存储在变量中的每个数值与变量类型一致。
4.值类型
值类型由System.ValueType类继承而来。
①简单类型
它们都是.NET系统类型的别名;由简单类型组成的常量表达式仅在编译时而不是运行时受检测;简单类型可以直接被初始化。
(1)整数类型
C#有八种数据类型:短字节型(sbyte)、字节型(byte)、短整型(short)、无符号短整型(ushort)、整型(int)、无符号整型(uint)、长整型(long)、无符号长整型(ulong)。
(2)字符类型
字符类型数据占用两个字节的内存,可以用单引号引起来的字符常量直接赋值。
除此之外,还可以用十六进制的转义符前缀\x,或Unicode表示为前缀\u,给字符型变量赋值,例如:
char char1='\x0046'; //字母“A”的十六进制表示
char char2='\u0046'; //字母“A”的Unicode表示
有些特殊字符无法直接用引号引起来给字符变量赋值,需要使用转义字符表示。
(3)实数类型
C#有三种实数类型:float(单精度型)、double(双精度型)、decimal(十进制小数型)。
其中double的取值范围最广,decimal的精度最高。
(4)布尔类型
表示“真”和“假”,用true和false来表示。
在C#中,不能将true值与整数非0值进行转换,也不能将false值与整型0值进行转换。
②枚举类型(enum)
枚举(enum)实际上是为一组在逻辑上密不可分的整数值提供便于记忆的符号。
例如:
enum Color
{
Red,Green,Blue
};
在定义的枚举类型中,每个枚举成员都有一个相对应的常量值。默认情况下,C#规定第一个枚举成员的值为0,后面每一个枚举成员的值加1递增。
也可以直接对枚举成员赋值,但只限于整数类型。如:
enum Color
{
Red=10,Green=20,Blue=30
};
声明方法:Color c1;在C#语言中,枚举不能作为一个整体被引用,只能使用“枚举类型名.枚举成员名”的方式访问枚举中的个别成员。
枚举成员本质上是一个枚举类型常量,不允许向其赋值,只能被读取。
③结构类型
如果不加声明,在结构中默认为私有(private)成员。
结构中还可以有构造函数、常数、方法等。
④可空类型
可空(Nullable)类型也是值类型,可以表示所有基础类型的值加上null。
局部可空变量必须赋一个初始值。声明方法如下:
int? nullableInt=1;
double? nullableDouble=5.46;
bool? nullableBool=null;
char? nullableChar='a';
或者用下面这种方式声明:
Nullable<int> nullableInt=1;
Nullable<double> nullableDouble=5.46;
Nullable<bool> nullableBool=null;
Nullable<char> nullableChar='a';
TIPS:这种语法只对值类型是合法的。
5.引用类型
引用类型不存储它们所代表的实际数据,而是存储对实际数据的引用。
C#提供的引用类型包括:类、接口、数组和委托。
①类类型
类是面向对象编程的基本单位,是对一组同类对象的抽象描述。
类类型又包括Object类型、string类型和用户自定义类型三种。
(1)Object类型
在C#中,所有类型都是直接或间接从类System.Object继承的。
对Object类型的变量声明,采用object关键字。可以将任何类型的值赋给Object类型的变量。
(2)string类型
string类专门用于对字符串进行操作,支持两种形式的字符串:正则字符串和原义字符串。
正则字符串如果包含特殊字符串,需要用转义符表示,如“D:\\student”。
原义字符串由@字符开头,不需要使用转义符,如“@D:\student”。
(3)用户自定义类型
可以使用class关键字自定义类类型。
②接口类型
C#不支持类的多重继承,通过接口可以实现多重继承的功能。
接口的用处:
通过接口可以实现不相关类的相同行为。
通过接口可以指明多个类需要实现的方法。
通过接口可以了解对象的交互界面,而不需要了解对象所对应的类。
接口的定义:使用interface关键字,一个接口的成员必须是抽象的方法、属性、事件或索引,这些抽象成员都没有实现体,并且所有接口成员隐含的都是公共访问类型。
一个类可以实现多个接口来达到类似于“多重继承”的目的,接口的继承关系用冒号(:)表示。例如:
class Bird: Flyable,Eatable
{
void MethodA();
void MethodB();
}
③数组类型
数组(Array)是一种常用的引用数据类型,是由一组相同数据类型的元素构成的。
数组的“秩”也称数组的维数,“秩”为1的数组称为一维数组,“秩”大于1的数组称为多维数组。
(1)一维数组的声明
数组类型[] 数组名;例如:
int[] Inum;
string[] Sname;
Student[] Scalss1;//Student是已定义类类型
(2)一维数组的创建
声明数组时并没有真正创建数组,可以使用new操作符来创建数组对象。例如:
int[] Inum=new int[10];
(3)一维数组的初始化
数据类型[] 数组名 = new 数据类型[] {初始值列表};或 数据类型[] 数组名 = {初始值列表};
使用new关键字创建的数组,如果没有初始化,则其元素都会使用C#的默认值。
(4)常见的数组操作
排序:Array.Sort(a);对数组a的元素从小到大排序
查找数组元素:Array.IndexOf()和Array.LastIndexOf()
Array.IndexOf()找到在数组中首次出现的元素;Array.LastIndexOf()查找元素最后一次出现的位置。
int[] a=new int[5] {2,6,4,2,1};
int b=Array.IndexOf(a,2);
Console.WriteLine(b.ToString()); //输出0
int c=Array.LastIndexOf(a,2);
Console.WriteLine(c.ToString()); //输出3
数组逆序:Array.Reverse(a);
复制数组:Array.Copy(a,b,a.Length); 将a中a.Length个元素复制到b中。