类型转换
把一个类型转成另一个类型,C#分为显示转换和隐式转换
主要区别分点在于:需不需要程序员自己写代码进行转换 (编译器是否自动转换)、是否存储数据丢失问题
1 >隐式转换:
编译器自动转换 不存在文件丢失场景 (例如 值类型把小空间的数赋值大空间的变量,引用类型场景:把派生类对象赋值基类对象)
int a = 10;
double b = a;
Console.WriteLine(b);//数据没有丢失
//把派生类对象赋值基类对象
//new Cat();派生类对象
//Animal ani ;基类变量
Animal ani = new Cat();//编译器自动转换
//隐式转换规则
//1、值类型 小区间往大区间可以直接转换
//2、引用类型 把子类对象赋值父类的对象
//3、有符号不能往无符号类型转换
2 >显示转换
需要程序员自己写代码 出现数据丢失的情况 也叫强制转换
//显示转换的语法:(要转换的类型)变量:(int)a
值类型显示转换
int a1 = 300;
byte a2 = (byte)a1;//1字节
Console.WriteLine(a2);//出现数据丢失44,300-256=44
int a3 = -129;
uint a4 = (uint)a3;
Console.WriteLine(a4);//出现数据丢失 结果是对应类型的互补位2^32-123=4294967167
引用类型的显示转换
//本质上Animal 转成Cat 转换失败 直接程序崩溃
//Animal ani1 = new Animal();//父类对象 大范围
//Cat cat = (Cat)ani1;//强制转换Cat类型 但是绷子上Animal对象,编译不会报错 ,运行会报错
//cat.speak();//报错
//如果本质上是Cat对象 强制转成Cat对象 可以正常转换的
Animal ani11 = new Cat();//本质是Cat对象
Cat cat11 = (Cat)ani11;
cat11.speak();
//类型安全转换
通过as进行转换
防止程序崩溃
Animal ani1 = new Animal();
Cat cat2 = ani1 as Cat;//转成失败 为null 转换失败程序不崩溃
if (cat2 != null)
{
cat2.speak();
}
通过is进行转换
if (ani1 is Cat c)//先判断再转换 先判断ani是不是Cat对象 如果是Cat对象 转成c对象
{
c.speak();
}
/*as 和is 的区别
*
* as
* 1、先类型转换 再转换
* 2、转换失败显示为null
* 3、 永远不会抛异常
* 4、不可使用值类型
* is
* 1、只有判断如果写成:anil is Cat c 格式 也可以达到先判断在转换的功能
* 2、返回值为 true 或者 false
* 3、永远不会抛异常
* 4、可以使用再任意类型
*
*/
cs
internal class Program
{
static void Main(string[] args)
{
int a = 10;
double b = a;
Console.WriteLine(b);//数据没有丢失
//把派生类对象赋值基类对象
//new Cat();派生类对象
//Animal ani ;基类变量
Animal ani = new Cat();//编译器自动转换
//隐式转换规则
//1、值类型 小区间往大区间可以直接转换
//2、引用类型 把子类对象赋值父类的对象
//3、有符号不能往无符号类型转换
//值类型显示转换
int a1 = 300;
byte a2 = (byte)a1;//1字节
Console.WriteLine(a2);//出现数据丢失44,300-256=44
int a3 = -129;
uint a4 = (uint)a3;
Console.WriteLine(a4);//出现数据丢失 结果是对应类型的互补位2^32-123=4294967167
//引用类型的显示转换
//本质上Animal 转成Cat 转换失败 直接程序崩溃
//Animal ani1 = new Animal();//父类对象 大范围
//Cat cat = (Cat)ani1;//强制转换Cat类型 但是绷子上Animal对象,编译不会报错 ,运行会报错
//cat.speak();//报错
//如果本质上是Cat对象 强制转成Cat对象 可以正常转换的
Animal ani11 = new Cat();//本质是Cat对象
Cat cat11 = (Cat)ani11;
cat11.speak();
//类型安全转换 通过as进行转换 防止程序崩溃
Animal ani1 = new Animal();
Cat cat2 = ani1 as Cat;//转成失败 为null 转换失败程序不崩溃
if (cat2 != null)
{
cat2.speak();
}
//还可以通过is进行转换
if (ani1 is Cat c)//先判断再转换 先判断ani是不是Cat对象 如果是Cat对象 转成c对象
{
c.speak();
}
}
class Animal { }
class Cat : Animal
{
public void speak()
{
Console.WriteLine("倍儿有面");
}
}
}
递归算法
递归算法:函数或者方法调用自己进行解决问题 , 核心思想就是复杂的问题分解为更为简单的子问题,知道子问题简单到能够直接求解(循环结束条件)
实例
cs
internal class Program
{
static void Main(string[] args)
{
//常用的案例
//1、斐波那契数列0 1 1 2 3 4 5 8...
Console.WriteLine(Shulei(5));
//2、计算阶乘 10! = 10*9*8*7...1 = 10*9!=10!9*8=...=10*9*8*7*...1!
Console.WriteLine(Jiecheng(10));
//3.打印文件所有子目录和文件
Dayin("D:\\vis项目\\_四周五\\_课2");
}
//打印文件
static void Dayin(string path,int count = 0)//count 缩进的个数
{
if (!Directory.Exists(path))//路径不存在,直接return
{
return;
}
string suojin = new string(' ', count);//两个空字符
//遍历当前文件夹下的文件 文件不能再次遍历 例如1.txt
foreach (string item in Directory.GetFiles(path))
{
//Console.WriteLine(item);
Console.WriteLine($"{suojin}文件:{Path.GetFileName(item)}");//Path.GetFileName()只显示文件的名字
}
//遍历文件夹
foreach (var item in Directory.GetDirectories(path))
{
//Console.WriteLine(item);
Console.WriteLine(Path.GetFileName(item));
//如果是文件夹需要再次遍历这个子文件夹
count += 2;
Dayin(item,count);
}
}
//封装 斐波那契数列
static int Shulei(int n)
{
if (n == 0) { return 0; }
if (n == 1) { return 1; }
return Shulei(n - 2) + Shulei(n - 1);
}
//阶乘
static int Jiecheng(int n)
{
if (n == 1) { return 1; }
return n*Jiecheng(n-1);
//10
//10*Jiecheng(9)
//10*9*Jiecheng(8)
//10*9*8*Jiecheng(7)......
}
}
编译错误
//错误分为两种错误
//编译错误,语法错误,
//运行错误:没有红色的语法错误,直到运行的时候才会把错误抛出来,例如 数组越界 类型转换错误 索引值超出界限
try...catch...catch...catch...
//try 尝试执行try里面的代码,
//如果错误,会被catch捕获错误,错误要是能解决,在catch中解决,如果不能解决,可以抛出异常
//如果使用多个catch,把具体的遗异常写在前面,把基类Exception写在最后一个
cs
internal class Program
{
static void Main(string[] args)
{
//如果直接写的话,可能遇见输入不是一个数字,程序会报字符串格式错误异常
//如果输入的是超出整型的范围,报太大太小的异常
inputNum:
try
{
string nums = Console.ReadLine();
int num = int.Parse(nums);
double sum = Math.Pow(10, num);
Console.WriteLine(sum);
}
//捕获字符串输入格式不正确
catch (FormatException)//FormatException 字符串输入格式不正确
{
Console.WriteLine("输入字符串格式不正确");
goto inputNum;
}
catch (OverflowException)
{
Console.WriteLine("超出范围的异常信息");
goto inputNum;
}
catch (Exception info)//Exception 异常类 所有异常的基类 所有异常都能捕获
{
//throw new Exception (info.Message);//info.Message 异常信息 采用throw 抛出异常 程序崩溃;
Console.WriteLine("无法预知的错误");//如果不想程序崩溃,打印错误信息
goto inputNum;
}
}
}
举例几种常见的报错
* Exception 异常基类
* FormatException格式不正确异常
* DivideByZeroException除数为0的异常
* OverflowException超出范围异常
* IndexOutOfRangeException 索引值越界异常
FileNotFoundException找不到文件的异常
装箱和拆箱
装箱:把值类型转成引用类型的过程
拆箱:把引用类型转成值类型的过程
int a = 10;
object b = a;
ArrayList list = new ArrayList();
list.Add(10);//把10转成object类型 装箱操作
list.Add(true);
int num1 = (int)list[0];//拆箱类型