二、类、对象、类成员
一、相关概念
1,类和对象(实例)
| 概念 | 物理世界 | 代码世界 |
|---|---|---|
| 类 | 人类 | Class Human |
| 对象/实例 | 小明(对象) | Human 小明 = new Human();//实例,其中小明是引用变量,new Human()已经算创建实例了 |
对象和实例基本等同,在物理世界中习惯叫对象,代码世界中习惯叫实例
2,属性、方法和事件
| 介绍 | 案例 | |
|---|---|---|
| 属性 | 存储数据 | h.Age; //没有括号 |
| 方法 | 类\对象能做什么 | h.Study(); //有括号 |
| 事件 | 类\对象通知其他类\对象的机制 |
namespaceBeyondYanyu{publicclassHuman{publicHuman(){}publicintAge{get;set;}// 属性publicdoubleHeight{get;set;}// 属性publicvoidStudy(){MessageBox.Show("beyondyanyu:age="+Age"height="+Height);}// 方法}publicstaticclassProgram{[STAThread]publicstaticvoidMain(){Humanh=newHuman();h.Age=25;// 使用 Age 属性h.Height=182;// 使用 Height 属性h.Study();// 使用 Study 方法}}}3,type方法
可以得到某个类(Form)的所有属性和方法
可以通过反射技术进行调用
usingSystem;usingSystem.Reflection;usingSystem.Windows.Forms;namespaceConsoleApp1{internalclassProgram{staticvoidMain(string[]args){TypemyType=typeof(Form);//拿到Form这个类的类型Console.WriteLine(myType.Name);//Form这个类的名称Console.WriteLine(myType.FullName);//Form这个类的全名Console.WriteLine(myType.BaseType.FullName);//Form这个类的父类的全名PropertyInfo[]pInfos=myType.GetProperties();//拿到Form这个类的所有属性foreach(PropertyInfopInfoinpInfos)//遍历属性{Console.WriteLine(pInfo.Name);}Console.WriteLine("==================++++++++++++++++=========================");MethodInfo[]mInfos=myType.GetMethods();//拿到Form这个类的所有方法foreach(MethodInfomInfoinmInfos)//遍历方法{Console.WriteLine(mInfo.Name);}}}}4,栈和堆
栈:方法(函数)调用
堆:存储对象(实例)
①栈溢出——StackOverflow
方法一:递归调用,直接搞崩内存
usingSystem;usingSystem.Reflection;usingSystem.Windows.Forms;namespaceConsoleApp1{internalclassProgram{staticvoidMain(string[]args){BadGaybadGay=newBadGay();badGay.BadMethod();}}classBadGay{publicvoidBadMethod(){intx=100;this.BadMethod();}}}方法二:直接stackalloc分配到栈上
usingSystem;usingSystem.Reflection;usingSystem.Windows.Forms;namespaceConsoleApp1{internalclassProgram{staticvoidMain(string[]args){unsafe{int*p=stackallocint[999999999];}}}}勾选项目的配置——允许不安全代码
②堆溢出
创建一个wpf项目
简单设置俩button,name分别为button1和button2,对应的Click事件分别为button1_Click和button2_Click
usingSystem.Collections.Generic;usingSystem.Windows;namespaceBeyondYanyu{/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>publicpartialclassMainWindow:Window{List<Window>winList;publicMainWindow(){InitializeComponent();}privatevoidbutton1_Click(objectsender,RoutedEventArgse){winList=newList<Window>();for(inti=0;i<500;i++){Windoww=newWindow();winList.Add(w);}}privatevoidbutton2_Click(objectsender,RoutedEventArgse){winList.Clear();}}}编译运行
可以看到对应的运行程序名称为我们创建项目时的名称BeyondYanyu
打开性能监视器(Performance Monitor)
win+r == perfmon
点击性能监视器,点一下×,表示不监视所有的内存占用情况
点击+,表示要观察具体某一个程序
Process下的Private Bytes
找到对应的运行程序
双击下面的红条,在图表下最大值设置为4028
可以看到内存使用率会变大
释放之后,GC也会找个时机去回收内存垃圾,不是立马释放回收
5,C#五大数据类型
- Classs——类
- Structures——结构体
- Enumerations——枚举
- Interfaces——接口
- Delegates——委托
第一列的五个:
object、string表示对应的类
class、interface、delegate用于定义数据类型(引用类型)
第二列:
bool、byte、…、ushort表示真正的数据类型,值类型
struct定义结构体,enum定义枚举
第三列:
true、false——bool类型的值
void——函数返回值为空;null——引用变量为空,不引用任何实例
var、dynamic——声明变量
蓝色的表示两层含义:
1,现成的常用的数据类型
2,基本数据类型(别的类型都是拿这些构成的)
二、变量、对象和内存
1,什么是变量
表面:变量的用途是存储数据
实际:变量表示了存储位置,并且每个变量都有一个类型,以决定什么样的值能够存入变量
变量名对应着变量的值在内存中的存储位置
变量一共有7种:静态变量、实例变量(成员变量,字段)、数组元素、值参数、引用参数、输出形参、局部变量
狭义的变量指局部变量,因为其它种类的变量都有自己的约定名称简单地讲,局部变量就是方法体(函数体)里声明的变量
变量的声明:有效的修饰符组合opt类型变量名初始化器opt
有效的修饰符组合opt,带有opt表示可有可无public int a = 0;
有效的修饰符组合opt:可有可无,public
类型:int
变量名:a
初始化器opt:可有可无,=0
总结:变量=以变量名所对应的内存地址为起点,以其数据类型所要求的存储空间的长度的一块内存区域
2,值类型和引用类型变量在内存中的存储
值类型的变量:
以byte/sbtye/short/ushort为例
值类型没有实例,所谓的“实例"与变量合而为一
引用类型的变量与实例:
引用类型变量与实例的关系:引用类型变量里存储的数据是对象的内存地址
变量的默认值:
常量(值不可改变的变量
装箱:把栈上的值类型封装成object类型的实例放在堆上
拆箱:把堆上的object类型的实例里面的值按照指定要求拆成目标数据类型存到栈上
