什么是类型

  • Type 又名数据类型(Data Type)

    • A data type is a homogeneous collection of values, effectively presented, equipped with a set of operations which manipulate these values.

    • 是数据在内存中存储时的“型号”

    • 小内存容纳大尺寸数据会丢失精度、发生错误

    • 大内存容纳小尺寸数据会导致浪费

    • 编程语言的数据类型与数据的数据类型不完全相同

  • 强类型语言与弱类型语言的比较

    • 强类型:编写程序时,程序中的数据受到数据类型的约束,即强类型编程语言

    • 弱类型:数据受类型约束不严格,或基本不受约束,即弱类型编程语言(如 JavaScript 动态类型)

    • C# 从 4.0 开始引入了 Dynamic,让它可以利用动态语言的一些特性,但 C# 依然是强类型编程语言

要成为优秀的开发人员,软件、硬件、操作系统都要精通。

附上一张后端工程师路线图.png来自 Github

类型在 C# 语言中的作用

一个 C# 类型中所包含的信息有:

  • 存储此类型变量所需的内存空间大小
  • 此类型的值可表示的最大、最小值范围
  • 此类型所包含的成员(如方法、属性、事件等)
  • 此类型由何基类派生而来
  • 程序运行的时候,此类型的变量被分配在内存的什么位置
    • Stack 简介
    • Stack overflow
    • Heap 简介
    • 使用 Performance Monitor 查看进程的堆内存使用量
    • 关于内存泄漏
  • 此类型所允许的操作(运算)

对一个程序来说,静态指编辑期、编译期,动态指运行期。
静态时装在硬盘里,动态时装在内存里。

反射示例

通过反射在运行期获取类的属性和方法。

  1. static void Main(string[] args)
  2. {
  3. Type myType = typeof(Form);
  4. Console.WriteLine(myType.BaseType.FullName + Environment.NewLine + myType.FullName);
  5. var pInfos = myType.GetProperties();
  6. foreach (var p in pInfos)
  7. {
  8. Console.WriteLine(p.Name);
  9. }
  10. var mInfos = myType.GetMethods();
  11. foreach (var m in mInfos)
  12. {
  13. Console.WriteLine(m.Name);
  14. }
  15. }

Stack & Heap

方法调用用到 Stack,Heap 存储对象。

Stack overflow

  • 函数调用过多(算法错误)

  • 在栈上分配了过多内存

不良的递归:
006,007 详解类型、变量与对象 - 图1

在栈上分配过大内存:
006,007 详解类型、变量与对象 - 图2

Process(进程)

  • 程序从硬盘加载到内存中执行就形成了一个进程。

  • 进程就是这个程序正在运行着的实例。

  • Process 的 ID 简称 PID。

Performance Monitor

Win + R,键入 perfmon 即可开启性能监视器。
通过性能监视器可以精确监视单个进程的内存消耗。
006,007 详解类型、变量与对象 - 图3

C# 语言的类型系统

006,007 详解类型、变量与对象 - 图4

面试问 C# 数据类型有那些,如下回答。

  1. C# 类型分为引用类型和值类型

  2. 引用类型包括类、接口、委托,值类型包括结构体和枚举

  3. 所有类型都以 Object 为自己的基类型

C# 的五大数据类型

Classes

  1. var myType = typeof(Form);
  2. Console.WriteLine(myType.FullName);
  3. Console.WriteLine(myType.IsClass);

Structures
在定义中还可以直接看到 MaxValue、MinValue。
006,007 详解类型、变量与对象 - 图5

Enumerations
006,007 详解类型、变量与对象 - 图6

  1. //
  2. // 摘要:
  3. // 指定窗体窗口如何显示。
  4. [ComVisible(true)]
  5. public enum FormWindowState
  6. {
  7. //
  8. // 摘要:
  9. // 默认大小的窗口。
  10. Normal = 0,
  11. //
  12. // 摘要:
  13. // 最小化的窗口。
  14. Minimized = 1,
  15. //
  16. // 摘要:
  17. // 最大化的窗口。
  18. Maximized = 2
  19. }

C# 类型的派生谱系

006,007 详解类型、变量与对象 - 图7

变量、对象与内存

006,007 详解类型、变量与对象 - 图8

变量表示了存储位置,并且每个变量都有一个类型,以决定什么样的值能够存入变量。

  • 变量名表示(对应着)变量的值在内存中的存储位置

  • 计算机系统通过变量的类型来分配给它对应大小的内存空间

字段
字段是属性的雏形,可以赋任意值。

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. var stu = new Student();
  6. // 人的年龄不应该为 -1
  7. stu.Age = -1;
  8. }
  9. class Student
  10. {
  11. public static int Amout;
  12. public int Age;
  13. public string Name;
  14. }
  15. }

引用类型的变量与实例

  1. Student stu;

计算机看到引用类型,直接给它分配 4 个字节,而且全部 Bit 置 0,告诉你这个变量没有引用任何实例。
006,007 详解类型、变量与对象 - 图9

  1. Student stu;
  2. stu = new Student();

现在,引用变量里面存的是实例的地址。
图中左侧是栈,右侧是堆。
006,007 详解类型、变量与对象 - 图10

  1. Student stu;
  2. stu = new Student();
  3. Student stu2;
  4. stu2 = stu;

006,007 详解类型、变量与对象 - 图11

变量的默认值

一旦变量在内存中分配好后,它的内存块就被统统刷成 0,这就是它的默认值。

局部变量没有默认值,因为 C# 为了避免不安全代码,要求局部变量必需有显式赋值。

装箱与拆箱

  1. int a = 100;
  2. object x;

006,007 详解类型、变量与对象 - 图12

装箱

  1. int a = 100;
  2. object x;
  3. x = a;

006,007 详解类型、变量与对象 - 图13

拆箱

  1. int a = 100;
  2. object x;
  3. x = a;
  4. int b = (int)x;
  5. Console.WriteLine(b);

006,007 详解类型、变量与对象 - 图14

参考

Docs Types and Variables