异常处理
finally 块,无论是否出现异常都会执行
class Program
{
static void Main(string[] args)
{
try
{
int[] array = { 1, 2, 3, 4 };
int num = array[4];
}
catch
{
Console.WriteLine("捕捉到程序出现错误");
}
finally
{
Console.WriteLine("无论是否出现异常都要走这一步");
}
Console.WriteLine("Test");
Console.ReadKey();
}
}
下面有一个求和的小案例
class Program
{
static void Main(string[] args)
{
int num1 = 0, num2 = 0;
Console.WriteLine("输入数字求和");
while (true)
{
try
{
num1 = Convert.ToInt32(Console.ReadLine()); //如果此行代码出现异常,剩下的代码将不会继续执行
break; //输入正确会跳出循环
}
catch
{
Console.WriteLine("请输入第一个有效数字");
}
}
while (true)
{
try
{
num2 = Convert.ToInt32(Console.ReadLine()); //如果此行代码出现异常,剩下的代码将不会继续执行
break;
}
catch
{
Console.WriteLine("请输入第二个有效数字");
}
}
int sum = num1 + num2;
Console.WriteLine("求和:"+sum);
Console.ReadKey();
}
}
面向对象编程
首先需要创建一个类
class Customer
{
public string name;
public string address;
public int age;
public string buyTime;
public void ShowInfo()
{
Console.WriteLine("姓名:" + name);
Console.WriteLine("地址:" + address);
Console.WriteLine("年龄:" + age);
Console.WriteLine("购买时间:" + buyTime);
Console.ReadKey();
}
}
然后在主程序调用这个类
class Program
{
static void Main(string[] args)
{
Customer customer; //声明一个变量(对象)
customer = new Customer(); //new 使变量初始化
customer.name = "老高";
customer.ShowInfo();
}
}
构造函数(构造方法)
- 构造函数是在使用new初始化变量的时候同步完成的。
- 当我们不写构造函数的时候,编译器会自动给我们提供一个无参的构造函数,当我们定义了构造函数之后,新的构造函数就会把默认的覆盖。
- 写入的数据不会被构造函数里面的数据覆盖
class Customer
{
public string name;
public string address;
public int age;
public string buyTime;
public Customer() //构造方法
{
name = "默认名字";
address = "默认地址";
age = 0;
buyTime = "默认购买时间";
}
public void ShowInfo()
{
Console.WriteLine("姓名:" + name);
Console.WriteLine("地址:" + address);
Console.WriteLine("年龄:" + age);
Console.WriteLine("购买时间:" + buyTime);
Console.ReadKey();
}
}
加入构造方法前后对比:
//前
姓名:老高
地址:
年龄:0
购买时间:
//后
姓名:老高
地址:默认地址
年龄:0
购买时间:默认购买时间
属性
定义属性的两种形式:
public int Age //普通定义属性的写法
{
set
{
if(value>=0) //通过set方法,可以在设置数值之前进行简单的校验
{
age = value;
}
}
get
{
return age;
}
}
//调用
customer.Age = 21;
public int age { get; set; } //利用系统定义好的
//调用
customer.age = 21;
输出结果:
姓名:老高
地址:默认地址
年龄:21
购买时间:默认购买时间
匿名类型
使用var 声明一个匿名类型,当初始化的时候,这个的变量就被确定下来,并且以后不可以修改哦
var var1 =34
堆和栈(程序运行时的内存区域)
我们把内存分为堆空间和栈空间
栈空间比较小,但是读取速度比较块
堆空间比较大,但是读取速度比较慢
栈的特点:
- 数据只能从栈顶插入和删除
- 把数据放到栈顶称为入栈(Push)
- 从栈顶删除数据称为出栈(Pop)
堆的特点:
堆是一块内存区域,与栈不用,堆里的内存能够以任意顺序存入和移除·
GC 垃圾回收机制
CLR的GC就是内存管理机制,我们写程序不需要关心内存的使用,因为这些CLR已经帮助我们完成了
值类型和引用类型
类型分为的两种,一种是值类型(整数,bool,struct ,char ,小数)和引用类型(string 数组,自定义的类,内置的类)。
值类型只需要一段单独的内存,用于存储实际的数据(单独定义的时候放在栈中)
引用类型需要两段内存:
- 第一段存储实际的数据,他总是位于堆中
- 第二段是一个引用,指向数据在堆中的存放位置(值类型放在栈里,引用部分如string是以地址的形式放到栈中,地址对应在堆里面的数据。释放内存时,先释放栈内存,此时堆中存在空引用,GC回收机制回收垃圾)
class Program
{
static void Main(string[] args)
{
//Test1();
Test2();
Console.ReadKey();
}
static void Test1()
{
string name1 = "Zhangsan11";
string name2 = "Lisi2";
name1 = name2;
name1 = "Wangwu3";
Console.WriteLine(name1 + "," + name2);
//输出结果: Wangwu3,Lisi2
//但使用引用类型赋值的时候,其实是赋值的一个引用
}
static void Test2()
{
Vector3 v1 = new Vector3();
v1.x = 100;
v1.y = 100;
v1.z = 100;
Vector3 v2 = new Vector3();
v2.x = 200;
v2.y = 200;
v2.z = 200;
v2 = v1; //v1 v2都指向 v1的引用
v2.x = 300;
Console.WriteLine(v1.x);
//输出结果:300
}
}