C Sharp/数据类型

C#的类型,分为值类型与引用类型两大类。值类型变量存放在栈上;引用类型在堆中分配空间。内建类型外,也可以定制类型。

值类型编辑

  • 函数参数传值。
  • 值类型没有/不需要调用构造函数。总是自动初始化。
  • 值类型的字段初始化为0或null.
  • 值类型不能赋值为null值,但可用Nullable类型
  • 值类型可以装箱。
  • 存储在栈中
  • 值类型包括简单类型、枚举类型和结构类型。

装箱和拆箱编辑

装箱(Boxing)就是从值类型到引用类型的转换。拆箱(unboxing)是从引用类型到值类型的转换。

 class Test
    {
        static void Mian()
        {
            int i = 3;
            object a = i;//装箱
            int j = (int)a;//拆箱
        }
    }

可空值类型编辑

可空值类型(nullable value type) T?表示该类型还可以取空值。例如:

int? a=null;

任何可空值类型T?是泛型结构System.Nullable<T>的实例。System.Nullable<T>有两个只读属性:Value与HasValue。

从可空值类型转化为基础值类型,可用空值结合运算符??或者System.Nullable<T>.GetValueOrDefault()。例如:

int? c = null;
int d = c ?? -1;
Console.WriteLine($"d is {d}");  // output: d is -1

引用类型编辑

引用类型的变量指向堆中的一块空间。为受管。使用构造函数初始化的对象,总是引用类型,CLR执行下述4步:

  1. The CLR计算堆中需要的内存;
  2. The CLR在堆中插入数据;
  3. The CLR标记内存空间中的占用结尾标记;
  4. The CLR返回新创建空间的引用

引用类型包括:

  • 接口
    • 装箱类型
    • 委托
    • 自定义类
  • 数组
  • 指针

说明:尽管string是类,但如果用到了相等运算符==或者!=时则表示比较string对象的值。

.NET框架中对应的类型编辑

// C#
public void UsingCSharpTypeAlias()
{
  int i = 42;
}

public void EquivalentCodeWithoutAlias()
{
  System.Int32 i = 42;
}
 ' Visual Basic .NET
 Public Sub UsingVisualBasicTypeAlias()
   Dim i As Integer = 42
 End Sub

 Public Sub EquivalentCodeWithoutAlias()
   Dim i As System.Int32 = 42
 End Sub

值类型的长度是固定的。引用类型都是继承自object类,其长度随平台而定。

.NET框架的类型有成员方法,如:

int i = 97;
string s = i.ToString();  // The value of s is now the string "97".

System.Int32类型实现了Parse()方法:

string s = "97";
int i = int.Parse(s); // The value of i is now the integer 97.

值类型可以装箱,然后可以拆箱:

object boxedInteger = 97;
int unboxedInteger = (int) boxedInteger;

装箱与拆箱不是类型安全的。编译器不会产生报错,弹运行时可能爆异常:

object getInteger = "97";
int anInteger = (int) getInteger; // No compile-time error. The program will crash, however.

C#内建类型与对应的.NET框架类型列表:

整型编辑

C# 别名 .NET 类型 比特长度 值域
sbyte System.SByte 8 -128 to 127
byte System.Byte 8 0 to 255
short System.Int16 16 -32,768 to 32,767
ushort System.UInt16 16 0 to 65,535
char System.Char 16 A unicode character of code 0 to 65,535
int System.Int32 32 -2,147,483,648 to 2,147,483,647
uint System.UInt32 32 0 to 4,294,967,295
long System.Int64 64 -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
ulong System.UInt64 64 0 to 18,446,744,073,709,551,615

浮点编辑

C# 别名 .NET类型 比特长度 精度 值域
float System.Single 32 7 digits 1.5 x 10-45 to 3.4 x 1038
double System.Double 64 15-16 digits 5.0 x 10-324 to 1.7 x 10308
decimal System.Decimal 128 28-29 decimal places 1.0 x 10-28 to 7.9 x 1028

其他预定义类型编辑

C# 类型 .NET 类型 比特长度 值域
bool System.Boolean 32 true or false, which aren't related to any integer in C#.
object System.Object 32/64 Platform dependent (a pointer to an object).
string System.String 16*length A unicode string with no special upper bound.

定制类型编辑

定制的值类型使用Template:C sharp/kwTemplate:C sharp/kw关键字。定制的引用类型使用Template:C sharp/kw关键字。

数组编辑

数组每个维度的长度可以不声明:

string[] a_str;

给数组变量赋值时,要指明每个维度的长度:

a_str = new string[5];

声明与初始化可以写在一起:

string[] a_str = new string[5];

数组是传引用。下例中两个参数的内容交换了:

static void swap (int[] a_iArray, int iI, int iJ)
{
    int iTemp = a_iArray[iI];

    a_iArray[iI] = a_iArray[iJ];
    a_iArray[iJ] = iTemp;
}

运行时确定数组长度:

    ushort[] a_usNumbers = new ushort[234];
    [...]
    for (ushort us = 0; us < a_usNumbers.Length; us++)
    {
        a_usNumbers[us] = us;
    }