什么是类型(type)

  • 数据类型(Data Type)
    • 数据类型是性质相同的值的集合,一些具体的操作是针对某些特定的数据类型的。
    • 是数据在内存中储存时的“型号”
    • 小内存容纳大尺寸数据会丢失精准度、发生错误
    • 大内存容纳小内存数据会导致浪费
    • 编程语言的数据类型与数据的数据类型不完全相同
      • 存储器、运算器、控制器组成CPU,硬件相关课程推荐《计算机组成原理》
  • 强类型语言与弱类型语言

    • C语言 强类型/弱类型
    • JavaScript 弱类型
    • C# 强类型
      • var 关键字:在第一次赋值时确定var变量的数据类型,之后不可再赋于其它类型的数据
      • dynamic 关键字:可以随着每一次赋值自由的切换数据类型(没有固定的数据类型)

        数据类型在C#语言中的作用

  • 一个C#数据类型中所包含的信息

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

      初遇反射概念

  • 反射:在运行过程中去调用某些类/对象的功能进行操作

    • type类:生成一个原类的“影子”,可以利用“影子”查询类的所有成员的属性(类名、继承关系、名称空间),但不能修改
    • Type.GetProperties()方法:返回当前 Type 的所有公共属性。
    • System.Reflection名称空间:通过检查托管代码中程序集、模块、成员、参数和其他实体的元数据来检索其相关信息的类型。
      • System.Reflection.MethodInfo类:发现方法的属性并提供对方法元数据的访问。有个构造方法可以想创建数组一样创建一个MethodInfo类的实例化数组。
  • 反射的实际意义:在实际项目中客户若须动态的的调用/修改某个实例的某个成员,需要利用反射机制查询类的属性、成员,再利用其他方法进行修改。(个人理解)
    ```csharp using System; using System.Reflection; //一个提供某种成员信息类库 using System.Windows.Forms;

namespace reflect { class Program { static void Main(string[] args) { Type myType = typeof(Form); //反射Form类的数据类型返回type类型的“影子”,再将这个“影子”实例化 //反射回来的“影子”实例化后可以查询原类的类名、父类名、名称空间 Console.WriteLine(myType.FullName); //打印“影子”的全称 Console.WriteLine(myType.BaseType.BaseType.FullName); //打印原类的父类的父类的名字,这里的BaseType可以多次使用

  1. PropertyInfo[] pInfos = myType.GetProperties(); //
  2. MethodInfo[] minfos = myType.GetMethods();
  3. Console.WriteLine("以下是属性的名称--------------------------");
  4. foreach (var p in pInfos)
  5. {
  6. Console.WriteLine(p.Name);
  7. }
  8. Console.WriteLine("以下是方法的名称--------------------------");
  9. foreach (var m in minfos)
  10. {
  11. Console.WriteLine(m.Name);
  12. }
  13. }
  14. }

}

  1. <a name="nMOqt"></a>
  2. ### Process(进程)
  3. - 程序从硬盘加载到内存中执行就形成了一个进程。<br />
  4. - 进程就是这个程序正在运行着的实例。<br />
  5. - Process 的 ID 简称 PID。<br />
  6. <a name="wXFsL"></a>
  7. ### Performance Monitor
  8. Win + R,键入 perfmon 即可开启性能监视器。<br />通过性能监视器可以精确监视单个进程的内存消耗。<br />![](https://cdn.nlark.com/yuque/0/2018/png/101969/1541985519904-df519375-baf0-4354-99e1-5f9d9643f944.png#align=left&display=inline&height=324&margin=%5Bobject%20Object%5D&originHeight=733&originWidth=1574&status=done&style=none&width=695)
  9. <a name="KBQb2"></a>
  10. ### C#语言的类型系统
  11. - C#的五大数据类型和
  12. - 类(class)
  13. - 结构体(structures)
  14. - 当我们对int按F12时发现int的定义是结构体(struct)<br />
  15. ![image.png](https://cdn.nlark.com/yuque/0/2020/png/1488644/1590890920396-9d778014-91a2-4e3e-b665-e0a2a1927359.png#align=left&display=inline&height=268&margin=%5Bobject%20Object%5D&name=image.png&originHeight=536&originWidth=1122&size=27809&status=done&style=none&width=561)
  16. - 枚举(Enumerations)
  17. ```csharp
  18. static void Main(string[] args)
  19. {
  20. Form form = new Form();
  21. form.WindowState = FormWindowState.Maximized;
  22. //对FormWindowState按F12会发现它是枚举类型
  23. form.ShowDialog();
  24. }
  25. --------------------------------------------F12----------------------------
  26. namespace System.Windows.Forms
  27. {
  28. [ComVisible(true)]
  29. public enum FormWindowState //enum :枚举关键字
  30. {
  31. Normal = 0, //默认大小
  32. Minimized = 1, //最小窗口
  33. Maximized = 2, //最大窗口
  34. }
  35. }
  • 接口(Interfaces)
    • 后续·单独讲
  • 委托(Delegates)
    • 后续单独讲

      C#类型的派生(继承)谱系

      image.png
  • 基类型(Object)

    • 引用类型(Reference Type)
    • 值类型(Value Type)

      变量、对象与内存

  • 什么是变量

    • 表面上,变量的用途是存储数据(实例化的对象)
    • 本质上,变量表示了储存位置(门牌号),并且每个变量都有一个类型(房间大小),以决定什么样的能够存入变量(合适数量的房客。少量的房客可以住进大房间,但是大量的房客不能住进小房间)
    • 变量一共有七种
      • 静态变量、实例变量(成员变量,字段)、数组元素、值参数、引用参数(ref)输出形参(out)、局部变量
    • 狭义的变量指局部变量,因为其他种类的变量都有自己约定名称
      • 简单地讲局部变量就是方法体(函数体)里声明的变量
    • 变量的声明(opt:表示非必须声明,有默认值)
      • 有效的修饰符组合(opt)、类型、变量名、初始化器(opt)
    • 总结:变量 = 以变量名为标识符所对应的内存地址为起点、以其数据类型所要求的储存空间为长度的1块内存区域。
  • 值类型变量
    • 值类型没有实例,其实就是实例与变量合为一体。(特殊)
    • 值类型分配内存过程:计算类型的大小,在栈内存中找到一块未被使用的内存用来储存相同大小的数据。
  • 引用类型的变量和实例
    • 引用类型变量与实例的关系:引用类型变量里储存的数据是对象的内存地址
    • 引用类型分配内存过程:当引用类型声明的时候,首先在栈内存中找到未被使用且具有4个字节大小的空间保留下来。当把声明实例化的时候在堆内存中找到等同于引用类型成员大小的内存,再将内存首地址编号的二进制数储存到刚声明时开辟栈内存的4个字节中。
  • 局部变量是在栈(stack)上分配内存
  • 变量的默认值
    • 如果变量在程序中定义没有赋初始值,编译器通不过
    • 如果变量定义在成员里面,默认值为0
  • 常量(值不可改变的变量)
    • 必须在初始化器中赋值
  • 装箱与拆箱(Boxing & Unboxing)

    • 装箱:首先object作为引用类型声明的时候就是在栈内存中开辟4个字节的内存,当把常规类型的对象赋值给object时,会在堆内存中开辟一个和栈内存中的数据(需要装箱的数据)大小相同的空间,且储存相同的值(二进制),然后在栈内存中储存堆中数据的首地址
    • 拆箱:会在栈内存中开辟一个拆箱后数据类型大小的内存空间,然后将之前在堆内存中装的数据赋值到栈内存里(多的舍去,少的补零)

      1. static void Main(string[] args)
      2. {
      3. int x = 100;
      4. object obj; //装箱
      5. obj = x;
      6. int y = (int)obj; //拆箱
      7. }