# 数据类型

  • 值类型:简单类型(如 int、float、bool 和 char)、枚举类型、结构类型、Nullable 值类型
  • 引用类型:类类型、接口类型、数组类型、委托类型

数据类型

描述类型
Unicode 字符(16 位)char
布尔值bool
有符号整数sbyte(8 位)< short(16 位)< int(32 位)< long(64 位)
正整数byte(8 位)< ushort(16 位)< uint(32 位)< ulong(64 位)
浮点数float(32 位)< double(64 位)
时间DateTime

可空类型:声明时加个 ? ,才可赋值为 null

# 值类型

类型描述范围默认值
bool布尔值True 或 FalseFalse
byte8 位无符号整数0 到 2550
char16 位 Unicode 字符U +0000 到 U +ffff'\0'
decimal128 位精确的十进制值,具有 28~29 个有效位数(-7.9 x 1028 到 7.9 x 1028) / 100 到 280.0M
double64 位双精度浮点型(+/-) 5.0 x 10-324 到 (+/-) 1.7 x 103080.0D
float32 位单精度浮点型-3.4 x 1038 到 + 3.4 x 10380.0F
int32 位有符号整数类型-2,147,483,648 到 2,147,483,6470
long64 位有符号整数类型-9,223,372,036,854,775,808 到 9,223,372,036,854,775,8070L
sbyte8 位有符号整数类型-128 到 1270
short16 位有符号整数类型-32,768 到 32,7670
uint32 位无符号整数类型0 到 4,294,967,2950
ulong64 位无符号整数类型0 到 18,446,744,073,709,551,6150
ushort16 位无符号整数类型0 到 65,5350

使用 sizeof() 获取类型或变量的大小

# 引用类型

# 对象类型 Object

Object obj;
obj = 100; // 装箱

# 动态类型 Dynamic

可以存储任何类型的值在动态数据类型变量中

dynamic d = 20;

# 字符串类型 String

字符串(String)类型是 System.String 类的别名

通过两种形式进行分配: 引号 和 @引号

String str = "zhudaidai";
// @(称作 "逐字字符串")将转义字符(\)当作普通字符对待,若要显示 ",则要打多个"
string str = @"C:\Windows"""; // 输出 C:\Windows"
等同于
string str = "C:\\Windows"; // 输出 C:\Windows
// @内可以任意换行:换行符及缩进空格都计算在字符串长度之内
string str = @"<script type=""text/javascript"">
  <!--
  -->
</script>";

# 指针类型

# 隐式(implicit)类型转换

编译器自动进行类型转换

# 不丢失精度的转换

《C# 定义文档》6.1.2 隐式数值转换

隐式数值转换为:

  • sbyte ➡ short、int、long、float、double 或 decimal
  • byte ➡ short、ushort、int、uint、long、ulong、float、double 或 decimal
  • short ➡ int、long、float、double 或 decimal
  • ushort ➡ int、uint、long、ulong、float、double 或 decimal
  • int ➡ long、float、double 或 decimal
  • uint ➡ long、ulong、float、double 或 decimal
  • long ➡ float、double 或 decimal
  • ulong ➡ float、double 或 decimal
  • char ➡ ushort、int、uint、long、ulong、float、double 或 decimal
  • float ➡ double
示例
int x = int.MaxValue;
long y = x;
Console.WriteLine(y);

# 子类向父类的转换

面向对象编程的一个核心概念 —— “多态”(polymorphism),多态就基于面向对象语言支持子类向父类的隐式转换

示例
class Program
{
  static void Main(string[] args)
  {
    Teacher t = new Teacher();
    Human h = t; // 当 t 转换为 h 后,在 h 里面就只能访问到 Human 类能访问的成员,不能再访问 Teach 方法
    Animal a = h;
    a.Eat();
  }
}
class Animal
{
  public void Eat()
  {
    Console.WriteLine("Eating...");
  }
}
class Human : Animal
{
  public void Think()
  {
    Console.WriteLine("Who i am?");
  }
}
class Teacher : Human
{
  public void Teach()
  {
    Console.WriteLine("I teach programmming");
  }
}

# 装箱

# 显式(explicit)类型转换

# 有可能丢失精度(甚至发生错误)的转换,即 cast

《C# 定义文档》6.2.1 显式数值转换
显式数值转换是指从一个 numeric-type 到另一个 numeric-type 的转换,此转换不能用已知的隐式数值转换(第 6.1.2 节)实现,它包括:

  • sbyte ➡ byte、ushort、uint、ulong 或 char
  • byte ➡ sbyte 和 char
  • short ➡ sbyte、byte、ushort、uint、ulong 或 char
  • ushort ➡ sbyte、byte、short 或 char
  • int ➡ sbyte、byte、short、ushort、uint、ulong 或 char
  • uint ➡ sbyte、byte、short、ushort、int 或 char
  • long ➡ sbyte、byte、short、ushort、int、uint、ulong 或 char
  • ulong ➡ sbyte、byte、short、ushort、int、uint、long 或 char
  • char ➡ sbyte、byte 或 short
  • float ➡ sbyte、byte、short、ushort、int、uint、long、ulong、char 或 decimal
  • double ➡ sbyte、byte、short、ushort、int、uint、long、ulong、char、float 或 decimal
  • decimal ➡ sbyte、byte、short、ushort、int、uint、long、ulong、char、float 或 double
示例
Console.WriteLine(ushort.MaxValue); // max ushort = 65535
uint x = 65536;
ushort y = (ushort)x;
Console.WriteLine(y); // y = 0

# 拆箱

# 使用 Convert 类

double x = System.Convert.ToDouble(tb1.text);
double y = System.Convert.ToDouble(tb2.text);
double result = x + y;
tb3.Text = Convert.ToString(result);
// or
tb3.Text = result.ToString();

# ToString 方法与各数据类型的 Parse/TryParse 方法

C# 的所有数据类型都源自于 Object 类,而 Object 类就有 ToString 方法,即 C# 中所有类型都有 ToString 方法

// Parse 只能解析格式正确的字符串数据类型
double x = double.Parse(tb1.Text);
double y = double.Parse(tb2.Text);
double result = x + y;
tb3.Text = result.ToString();
// TryParse
double x;
if (double.TryParse(tb1.Text,out x))
{
  double y = Convert.ToDouble(tb2.Text);
  double result = x + y;
  tb3.Text = result.ToString();
}

# 自定义类型转换操作符

示例:显式类型 —— 让石头类支持显式转换为猴子
class Program
{
  static void Main(string[] args)
  {
    Stone stone = new Stone();
    stone.Age = 5000;
    Monkey wukongSun = (Monkey)stone;
    Cossnsole.WriteLine(wukongSun.Age); // 10
  }
}
class Stone
{
  public int Age;
  // 转换器写在被转换类型里面
  public static explicit operator Monkey(Stone stone)
  {
    Monkey m = new Monkey()
    m.Age = stone.Age / 500;
    return m;
  }
}
class Monkey
{
  public int Age;
}
示例:隐式类型
class Program
{
  static void Main(string[] args)
  {
    Stone stone = new Stone();
    stone.Age = 5000;
    Monkey wukongSun = stone;
    Cossnsole.WriteLine(wukongSun.Age); // 10
  }
}
class Stone
{
  public int Age;
  // 转换器写在被转换类型里面
  public static implicit operator Monkey(Stone stone)
  {
    Monkey m = new Monkey()
    m.Age = stone.Age / 500;
    return m;
  }
}
class Monkey
{
  public int Age;
}