基础加强
基础加强
- Main函数是什么?
 - 在程序中使用Main函数有什么需要注意的地方?
 - CLR是什么?
 - 程序集是什么?
 - 当运行一个程序集的时候,CLR做了什么事情?
 - 值类型的默认值是什么?
 - 声明一个变量时在内存中做了什么事情?
 - 初始化一个变量的时候又在内存中做了什么事情?
 - new关键字做的事情?
 - 数组一旦创建后,能不能修改数组的长度?
 - 如何声明一个多维数组?
 - 如何获取多维数组的总长度?
 - 如何声明一个交错数组?
 - 交错数组的本质是什么?
 - 为什么要有方法?
 - 如何实现方法的重载?
 - 引用参数(ref)和输出参数(out)的相同点与不同点?
 - 在什么情况下使用引用参数(ref)和输出参数(out)?
 - 可变参数与普通数组参数的区别?
 - 面向对象的三大特征是什么?
 - 类和对象的关系?
 - 创建某一个类的对象的时候,在内存中做了什么事情?例如 Person p = new Person();
 - 属性存在的目的是什么?
 - 访问修饰符有哪些并分别每一个访问修饰符?
 - 为什么要有构造函数呢?
 - 什么是封装?
 - 封装的目的是什么?
 - 类的命名规则是什么?
 - 什么是类型?
 - this关键字在方法中使用时,它代表什么?
 - 值类型变量的初始化(内存分配)?
 - 继承的好处?
 - 继承的单根性
 - 继承的传递性
 - 当存在继承关系的时候,在子类中如何访问父类的非私有成员?
 - 什么是里氏替换原则?
 - 子类与父类对象之间的转换?
 - is 和 as 操作符的用处和区别?
 - override可以重写哪些 "类型" 的方法?
 - 什么是多态?
 - 抽象方法只能定义在抽象类中吗?
 - CLR什么时候加载类?
 - 当存在继承关系的时候,创建子类对象的时候会不会创建父类对象呢?
 - 如果子类和父类存在同名但没有重写关系的方法的时候,那么会调用哪个方法?
 - 如果子类和父类存在同名且有重写关系的方法,那么会调用那个方法?
 - 虚方法和抽象方法的相同点与不同点?
 - 子类中的base关键字指向的是子类对象还是父类对象?
 - 它本身的类型是子类类型还是父类类型呢?
 - 为什么要有抽象类?
 - 使用多态的好处是什么?
 - 什么情况下的类不能被实例化?
 - 什么情况下抽象类的子类不需要实现父类的抽象成员?
 - 虚方法(虚拟成员)和抽象方法(抽象成员)能不能被私有化?
 - 静态成员能不能被标记为virtual、override 或 abstract?
 - 接口的命名规则?
 - 什么是接口?
 - 接口能包含的成员有哪些?
 - 接口的访问权限修饰符只能是哪两种?
 - 接口能不能实现接口?
 - 如果一个抽象类继承了一个接口,那么将继承的方法设置为抽象方法,还是去实现该方法?
 - 使用接口应注意什么事项?
 - 显式接口和隐式接口?
 - 接口与抽象类的区别?
 - 转换分类?
 - ToString()方法?
 - Parse()和TryParse()方法的区别?
 - 什么时候加载静态成员
 - 什么时候用静态成员
 - 在普通类和静态类中的区别
 - 静态类的继承
 - 类和成员的访问修饰符
 - 结构本质是什么?
 - 值类型和引用类型的选择
 - new关键字的作用
 - 类和结构的区别
 - 值类型和引用类型作为参数传递的区别
 - 访问级别约束
 - 析构函数
 - 为什么不能在结构体中定义析构函数
 - 字符串常用方法
 - ==运算符和Equals()方法的区别
 - 字符串的恒定性
 - StringBuilder 和 String 的区别?
 - 枚举本质是什么?
 - 枚举项的相关问题
 - IEnumerable接口
 - 集合
 - 动态数组和 泛型集合的不同点和优缺点
 - 泛型list的常用方法
 - 哈希表内部机制原理
 - 哈希表存取操作原理
 - 泛型集合引用命名空间
 - List和ArrayList的性能比较
 - 应该使用try语句块的情况
 - Windows Form程序相关文件
 - Path类相关方法
 - 操作目录(Directory类)相关方法
 - 操作文件(File)相关方法
 - DirectoryInfo(文件夹的一个“类”,用来描述一个文件夹对象)相关方法
 - using语句的本质
 - 文件操作注意问题
 - 序列化和反序列化的区别
 - Serializable特性
 - 什么是委托?
 - 委托的目的是什么?
 - 委托的适用情形?
 - 冒泡排序?
 - 匿名方法是什么?
 - 多播委托是什么?
 - 事件本质是什么?
 - 委托和事件的区别是什么?
 
- Main函数是什么?
 - 在程序中使用Main函数有什么需要注意的地方?
- Main函数不能变,有且只有一
 
 - CLR是什么?
- 公共语言运行时
 - Common Language Rentime
 
 - 程序集是什么?
- 编译后代码的集合(包括exe和dll);加载项目里所有的类到内存,并找到其中的主函数,并作为默认的启动函数调用执行
 
 - 当运行一个程序集的时候,CLR做了什么事情?
- 加载项目所有的类到内存,并找到其中的主函数作为默认的启动函数调用执行,但是,如果项目中,包含一个以上的主函数时CLR不知道从那里开始,如果项目中,没有包含主函数的话,CLR也不知道如何启动
 
 - 值类型的默认值是什么?
- 如果没有赋值且是全局变量或字段
- Int默认为0
 - Bool 默认为false
 - Eumn
 - 结构体
 
 - 如果是局部变量就必须赋值
 
 - 如果没有赋值且是全局变量或字段
 - 声明一个变量时在内存中做了什么事情?
- 在栈中开辟空间,并将变量放入空间中,默认值为Null
 
 - 初始化一个变量的时候在内存中做了什么事情?
- 如果是值类型直接放在栈中
 - 如果是引用类型,在堆中开辟空间,将堆中的地址指针放入栈中
 
 - new关键字做的事情?
- 开辟空间
 - 创建对象
 - 调用构造函数
 
 - 数组一旦创建后,能不能修改数组的长度?
- 不能,创建时在内存中开辟了一段连续的空间
 
 - 如何声明一个多维数组?
- string[,] strs={{"1","1"},{"1","1"}};
 
 - 如何获取多维数组的总长度?
- 各个纬度元素的乘积
 
 - 如何声明一个交错数组?
- int[] [] arr=new int [3] [3];
 
 - 交错数组的本质是什么?
- 一个数组的数组,也就是数组的元素就是一个一维数组
 
 - 为什么要有方法?
- 为了复用
 - 封装具体实现
 
 - 如何实现方法的重载?
- 方法名相同,方法签名不同,和返回值无关
 
 - 引用参数(ref)和输出参数(out)的相同点与不同点?
- 相同点:传递的都是引用
 - 不同点:out侧重于输出参数,ref侧重于修改参数,out必须方法返回前赋值,ref必须在传入之前赋值
 
 - 在什么情况下使用引用参数(ref)和输出参数(out)?
- 如果方法有多个返回值,则可以用out或者ref。只不过ref侧重于修改(即将值传进去修改后在拿出来),而out是为了从方法中获得一个值后拿到方法外使用
 
 - 可变参数与普通数组参数的区别?
- 必须放在参数列表最后
 - 每个方法中有且只有一个params
 - 如果没有给params赋值,长度就自动初始化为0
 
 - 面向对象的三大特征是什么?
- 封装
 - 继承
 - 多态
 
 - 类和对象的关系?
- 类是抽象的,对象是具体的实现
 - 类是用来描述实物的,是针对具体存在的一种描述,对象是这类事务存在的具体实现,按照类的描述来创建一个可供我们使用的实例
 
 - 创建某一个类的对象的时候,在内存中做了什么事情?例如 Person p = new Person();
- 开辟空间,创建对象,调用构造函数(在内存的堆中开辟空间,创建Person对象,然后在内存的栈中开辟一空间放一个p,然后将Person对象在堆中的引用地址赋值给对象p)
 
 - 属性存在的目的是什么?
- 封装字段
 - 为了对字段的操作设置规则
- 本质上是两个方法:get();set();
 
 
 - 访问修饰符有哪些并分别每一个访问修饰符?
- Public 公有的
 - private 私有的
 - Internal 程序集内共享,如果不写修饰符默认就是Internal
 - Protected 受保护的
 - Extern 供外部访问
 
 - 为什么要有构造函数呢?
- 主要方便程序员在实例化对象中一些属性字段初始化赋值
 
 - 什么是封装?
- 就是把重复的代码包起来
 
 - 封装的目的是什么?
- 复用
 - 隐蔽实现
 - 修改方便
 
 - 类的命名规则是什么?
- 帕斯卡方式,首字母大写
 - 变量,骆驼命名方式,首字母小写
 
 - 什么是类型?
- 用来定义某一种数据在内存里开辟空间的大小
 
 - this关键字在方法中使用时,它代表什么?
- 所在类的堆里面的对象
 - this指当前类的对象,或者他的父类的类对象
 
 - 值类型变量的初始化(内存分配)?
- 当变量是一个类的成员变量的时候,那么该变量是跟随类的对象存在于堆内存,但对象引用断开时,等垃圾回收器进行清理时便销毁
 
 - 继承的好处?
- 提高代码的复用
 - 实现多态
 
 - 继承的单根性
- 一个类只有一个父类
 
 - 继承的传递性
- 指子类“获得”父类所有非私有的成员
 
 - 当存在继承关系的时候,在子类中如何访问父类的非私有成员?
- 当存在继承关系的时候,子类的this同时可以指向父类的非私有成员,base就是存在于子类对象里,用来指向父类对象的指针
 
 - 什么是里氏替换原则?
- 在声明的时候,子类替换父类所在的位置
 
 - 子类与父类对象之间的转换?
- 子类可以强转为父类,反之无法实现
 
 - is 和 as 操作符的用处和区别?
- is就是出去对类型的判断,返回true和false。如果一个对象是某个类型或是其父类型的话就返回为true,否则的话就会返回为false,is永远不会抛出异常
 - as关键词只能判断、转换引用类型,as首先测试转换是否合法,如果合法就转换,否则返回Null。关键词Null表示空引用,不会抛异常
 
 - override可以重写哪些 "类型" 的方法?
- 虚方法(virtual)
 - 抽象方法(abstract)
 
 - 什么是多态?
- 就是用某个子类来实例化父类,调用的是父类的抽象方法(虚方法),但实际执行的是子类实例重写的方法
 
 - 抽象方法只能定义在抽象类中吗?
- 抽象方法只能定义在抽象类中
 - 抽象方法必须在子类中实现,除非子类也是抽象类
 - 抽象成员不能是私有的(private)
 
 - CLR什么时候加载类?
- 是在第一次在代码中遇到这个类的时候才加载类的静态成员和信息
 
 - 当存在继承关系的时候,创建子类对象的时候会不会创建父类对象呢?
- Person p=new Student()
 - 当我们new一个子类的时候,在内存中,只有一个子类对象
 
 - 如果子类和父类存在同名但没有重写关系的方法的时候,那么会调用哪个方法?
- 如果子类和父类存在同名但没有重写关系的方法,那么调用时,如果父类变量调用,则调用父类方法,如果是子类变量调用,则调用子类的方法
 
 - 如果子类和父类存在同名且有重写关系的方法,那么会调用那个方法?
- 如果子类和父类存在同名且有重写关系的方法,那么不管变量是什么类型,调用的都是子类的方法
 
 - 虚方法和抽象方法的相同点与不同点?
- 相同点
- 抽象方法和虚方法都能被重写
 - 都不能为private
 
 - 不同点
- abstract和virtual的关键字不同
 - 抽象方法一定没有方法体,而虚方法必须有方法体
 - virtual方法的子类可以重写父类方法也可以不重写,而抽象方法的所在的类的子类必须重写父类方法
 - 抽象方法必须在抽象类中声明,而虚方法可以存在于任何类里面
 
 
 - 相同点
 - 子类中的base关键字指向的是子类对象还是父类对象?
- 子类对象
 
 - 它本身的类型是子类类型还是父类类型呢?
- 父类类型
 - base就是子类对象本身,只不过类型是父类的
 
 - 为什么要有抽象类?
- 抽象类存在的目的就是制定规则,而不是具体实现,(为了约束子类的行为),具体实现交给子类完成
 
 - 使用多态的好处是什么?
- 低耦合,代码之间关联小,便于维护
 - 作用:把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化
 
 - 什么情况下的类不能被实例化?
- abstart(抽象类)
 - static(静态类)
 - private(构造函数私有化)
 
 - 什么情况下抽象类的子类不需要实现父类的抽象成员?
- 子类本身也是抽象类
 
 - 虚方法(虚拟成员)和抽象方法(抽象成员)能不能被私有化?
- 不能(编译报错)
 - 深层原因:他们两者存在的目的就是为了让子类去重写,如果私有化了就没意义了
 
 - 静态成员能不能被标记为virtual、override 或 abstract?
- 不能
 
 - 接口的命名规则?
- I开头
 - able结尾,表示有什么能力
 
 - 什么是接口?
- 特殊的抽象类
 - 完全是为了约束类的行为
 
 - 接口能包含的成员有哪些?
- 只能有方法、属性、索引、和事件的声明
 
 - 接口的访问权限修饰符只能是哪两种?
- public
 - internal
 
 - 接口能不能实现接口?
- 能实现
 
 - 如果一个抽象类继承了一个接口,那么将继承的方法设置为抽象方法,还是去实现该方法?
- 都可以
 
 - 使用接口应注意什么事项?
- 接口的成员不能加访问修饰符
 - 接口的成员不能有任何实现
 - 实现接口的子类必须实现接口的全部成员
 - 接口中只有方法、属性、事件、索引器,不能有字段
 - 一个类可以同时继承一个类并实现多个接口,如果一个子类同时继承了父类A,并实现接口IA,那么在语法上A必须在写在IA的前面,因为类是单继承的,而接口可以实现多个
 - 向上转型
 - 单一职责原则:避免定义体积庞大的接口,只把相关联的一组成员定义的接口中,如果不这样做就会造成接口污染
 
 - 显式接口和隐式接口?
- 类实现几口,可以显式的实现接口里的方法,但注意:旦使用显式接口里的方法后,那么该方法只能被接口变量调用
 - 
IFlyable fly = new Bird();
 - 
fly.Fly(); //正确
 - 
Bird fly = new Bird();
 - 
fly.Fly(); //错误
 
 - 接口与抽象类的区别?
- 抽象类:
- 抽象方法只作声明,而不包含实现,可以看成是没有实现体的虚方法。
 - 抽象类不能被实例化。
 - 
抽象类可以但不是必须有抽象属性和抽象方法, 但是一旦有了抽象方法, 就一定要把这个类声明为抽象类
 - 
具体子类必须实现基类的抽象方法
 - 
抽象子类可以实现基类的抽象方法,也可以不实现。如果不实现,则其具体子类必须实现它们
 
 - 
接口
- 接口不能被实例化
 - 
接口只能包含方法声明
 - 
接口的成员包括方法、属性、索引器、事件
 - 
接口中不能包含常量、字段(域)、构造函数、析构函数、静态成员
 - 
接口中的所有成员默认为public,因此接口中不能有private修饰符
 - 
子类必须实现接口的所有成员
 - 
一个类可以直接实现多个接口,接口之间用逗号隔开
 - 
一个接口可以有多个父接口,实现该接口的类必须实现所有父接口中的所有成员
 
 
 - 抽象类:
 - 转换分类?
- 隐式转换
 - 显示转换
 
 - ToString()方法?
- 是object对象的一个虚方法,如果不重写就返回类全名称
 - 可以重写该方法
 
 - Parse()和TryParse()方法的区别?
- 相同点
- 都是针对值string类型进行的值类型转换
 
 - 不同点
- 返回值不一样,Parse返回转换成功的类型,TryParse返回Bool值
 - Parse转换失败会抛异常,TryParse不会抛异常
 - Parse通过返回值返回结果,TryParse通过out返回结果
 
 
 - 相同点
 - 什么时候加载静态成员
- 在编译的时候
 
 - 什么时候用静态成员
- 在整个程序内部共享的数据,通常用做通用工具类,比如SQLHelper类
 
 - 在普通类和静态类中的区别
- 静态类用state修饰
 - 静态类不能被实例化
 - 静态类中只能包含静态成员
 - 静态成员属于类所有,非静态成员属于类的实例所有
 - 在实例方法中可以直接调用静态成员,而静态方法中不能直接调用实例方法
 - 静态类和静态成员创建后始终使用同一块内粗,而使用实例的方式会创建多块内存
 - 静态构造函数不能有参数,也不能有访问访问修饰符(默认是Private)
 
 - 静态类的继承
- 不能被继承
 - 只能继承Object
 
 - 类和成员的访问修饰符
- 类的访问修饰符只有两种:public,internal(默认)
 - 成员的访问修饰符有:public,protected,private(默认)
 
 - 结构本质是什么?
- 结构体的本质是值类型
 
 - 值类型和引用类型的选择
- 值类型:主要是用来封装一组数据,并为数据提供一种简单的处理方式
 - 引用类型:
- 主要用来封装数据和行为
 - 使用面向对象的特征
 - 当类型中的成员比较多的时候(存放在堆里)
 
 
 - 结构 new关键字的作用
- 使用new关键字创建对象后,所用的成员变量都已经存在,并有默认值(值类型);如果没有用new关键字,则需要程序员手动为用到的成员变量赋值
 
 - 类和结构的区别
- 结构是值类型,是分配在内存的栈上的,而类是引用类型,是分配在内存的堆上的
 - 结构不能被继承,因为结构是值类型,隐式继承自System.ValueType
 - 结构是值传递的(赋值传递),而类是引用传递的
 
 - 值类型和引用类型作为参数传递的区别
- 结构是值传递的(赋值传递),而类是引用传递的
 
 - 访问级别约束
- 子类的访问级别不能比父类的高
 - 类中的属性或字段的访问级别不能比所对应的类型访问级别高
 - 方法的访问级别不能比方法的参数和返回值的访问级别搞,比如当方法的参数传递的是一个类的对象时,那么此时这个类的对象的访问级别要高于当前方法的访问级别
 
 - 析构函数
- 一个类只能有一个析构函数
 - 无法继承和重载析构函数
 - 我们无法手动调用析构函数,因为他是被GC自动调用的
 - 析构函数没有访问修饰符也不能有参数
 - 不能在结构体中定义析构函数
 
 
class MyDispose{~MyDispose(){...//在这里写释放资源的代码}}
- 为什么不能在结构体中定义析构函数
- 因为结构是值类型,而值类型是存储在栈汇总的,栈中的数据在用完之后就立即销毁了,而析构函数就是用泪释放资源的,一般存储在堆中的引用类型才需要GC去释放
 
 - 字符串常用方法
- (Last)IndexOf:用来查找某个字符或者字符串,在一个特定字符串对象里的下标
 - SubString:截取
 - Split():根据特定字符来分割字符串,并返回分割后的字符串的数组,可以用foreach读取
 - Join:静态方法
 - Format():静态方法
 - Replace():替换完要接收,产生一个新的字符串
 - Trim():去首尾空格
 
 - ==运算符和Equals()方法的区别
- "=="如果比较的是值类型,则比较两个对象的值;如果比较的是引用类型,则比较两个对象的引用地址是否相同
 - Equals()是Object里的虚方法,默认用==进行比较,但是大部分微软的类,及用户定义的类,都重写了该虚方法,也就是微软和用户各自为自己编写的Object的子类定义了相等比较规则
 
 - 字符串的恒定性
- 当字符串在内存中已经被创建后,程序员在此创建相同值的字符串对象时,CLR做了优化,直接把第一个字符串的引用赋给了第二个变量,也就是说,前后两个字符串变量保存了相同的字符串对象引用
 - 如果代码里是直接将两个字符串相加,那么在CLR编译IL的时候,就会直接将相加拼接后的新字符串作为变量的值;如果代码里是将两个字符串变量相加的话,那么,CLR会在编译IL时,调用string.Concat(string,string)方法来将两个字符串变量的值拼接,最后返回一个新的字符串变量
 
 - StringBuilder 和 String 的区别?
- String在进行运算时(如赋值、拼接等)就会产生一个新的实例,而StringBuilder则不会。所以在大量字符串拼接货频繁对某一个字符串及in行操作时最好使用StringBuilder,不要使用String如果要操作一个不断增长的字符串,尽量不用String类,改用StringBuilder类
 - 两个类的工作原理不同:String类是一种传统的修改字符串的方式,它确实可以完成把一个字符添加到另一个字符串上的工作没错,但是在.Net框架下,这个操作实在是划不来,因为系统先是把两个字符串写入内存,接着删除原来的String对象,然后创建一个String对象,并读取内存中的数据赋给该对象。这一来二去的,耗了不少事件,而使用System.Text命名空间下面的StringBuilder类就不是这样了,它特工了Append方法,能够在现有对象的基础上进行 字符串的修改,简单而且直接,当然,一般情况下觉察不到这两者的效率差异,但如果你要对某个字符串进行大量的添加操作,那么StringBuilder类所耗费的事件和String类简直不是一个数量级的
 
 - 枚举本质是什么?
- 枚举的本质就是类
 
 - 枚举项的相关问题
- 如果为第一个枚举项赋了一个int值,那么后面的枚举项依次递增
 - 可以将枚举强转成他所代表的int值
 - 因为枚举项都对应的int值,所以Switch把他当成int看
 - C#的枚举项都是常量
 - 不能定义方法、属性、事件
 - 多个枚举有相同数值时,数值强转时,会返回其中最后一个枚举项
 - 枚举项的数值类型int long shot...
 - 值类型,因为继承System.ValueType
 
 - IEnumerable接口
- 只要实现该接口就可以使用foreach(封装了迭代器)
 - IEnumerable接口主要包含
- GetEnumerable方法(获取迭代器)
 - MoveNext方法(检查是否存在循环的下一个元素)
 - GetCurrent方法(获得当前循环到的元素)
 
 
 - 集合
 - 
- 主要分为非泛型集合和泛型集合
 - 非泛型集合
 - 
- Arraylist
 - 里面真正存储数据的是一个Object[]数组,它对应的泛型是List<T>
 - HashTable
 - 非泛型的键值对集合,它对应的泛型是Dictionary<TKey,TValue>
 
 - 泛型集合
 - 
- List<T>
 - Dictionary<K,V>
 
 
 - 动态数组和 泛型集合的不同点和优缺点
 - 
- 不同点
 - 动态数组对元素没有任何约束,可以添加任何元素,其根本原因是内部存储元素的是一个Object数组
 - 泛型集合是带元素类型约束的集合
 - 尽可能使用泛型集合
 - 优缺点
 - 避免了装箱、拆箱操作带来的性能损耗
 - 在添加元素时随参数类型进行检查(编译时就检查)
 
 - 泛型list的常用方法
 - 
- Add()
 - AddRange()
 - Insert()
 - InsertRange()
 - Remove()
 - RemoveAt()
 - Resverse()
 
 - 哈希表内部机制原理
 - 
- 内部就是一个结构体数组(bucket)
 
 
        private struct bucket
{
public object key;
public object val;
public int hash_coll;
}
{
public object key;
public object val;
public int hash_coll;
}
- 如何存?
 - 下标是根据key的hash值算出来的。当我们向Hashtable中Add元素时,元素储存在Hashtable的数组里的下标是根据添加key的hash值算出来的(但因为hash值取模数组长度,所以肯定不会超过当前数组长度)
 - 每个对象算出的Hashcode并不是唯一的,有可能出现多个对象的Hashcode相同
 - 解决机制
 - 
- 再Hash一次
 - 桶装模式,将两个相同的Hashcode的对象装入一个位置
 
 - 当新增时,Hashtable里的容器数组已经满了,则以数组的两倍扩容
 - 如何取?
 - 当我们从Hashtable里取元素时(根据key来取),会根据key的hash值算出要取的元素的下标,并比较元素里的key和当前要找的key参数的hash值是否相等,同时还要比较两个key的引用是否一致,如果都满足,则确定找到要取的元素
 - 泛型集合引用命名空间
 
- 
ChangeExtension(修改文件的后缀,“修改”支持字符串层面的,没有真的给文件改名)
 - 
Combine(将两个路径合成一个路径【自动处理路径分隔符的问题】)
 - 
GetDirectoryName(得到文件的路径名)
 - 
GetExtension(得到文件的扩展名)
 - 
GetFileName(得到文件路径的文件名部分)
 - 
GetFileNameWithoutExtension(得到去除扩展名的文件名)
 - 
GetFullPath(得到文件的全路径,可以根据相对路径获得绝对路径)
 - 
GetTempFileName(得到一个唯一的临时文件名)
 - 
GetTempPath(得到临时文件夹的路径)
 - 操作目录(Directory类)相关方法
 
- 
Delete(删除目录【recursive表示是否递归删除】)
 - 
Exists(判断目录是否存在)
 - 
move(移动)
 - 
GetDirectories(得到一个目录下的子目录)
 - 
GetFiles(得到一个目录下的文件)
 - 操作文件(File)相关方法
 
- 
AppendAllText(将文本contents附加到文件path中【如果文件不存在,则创建】)
 - 
Exists(判断文件path是否存在)
 - 
ReadAllLines(读取文本文件到字符串数组中)
 - 
ReadAllText(读取文本文件到字符串中)
 - 
WriteAllText(将文本contents保存到文件path中,会覆盖旧内容)
 - 
WriteAllLines(将字符串数组逐行保存到文件path中,会覆盖旧内容)
 - 
Copy(文件拷贝【true表示当文件存在时“覆盖”,如果不加true,则文件存在报异常】)
 - 
Create(创建文件)
 - 
Delete(如果文件不存在?不存在,不报错)
 - DirectoryInfo(文件夹的一个“类”,用来描述一个文件夹对象)相关方法
 
- 当使用文件流的时候,在关闭流的时候数据才会保存到文件中
 - Close执行了Dispose()并回收对象
 - 所有要使用using关键字来释放资源的类都必须实现IDisposable接口
 - 获取当前exe文件执行的路径用(Assemby.GetExecutingAssembly().Location不要用Directory.GetCurrentDirectory(),因为获取的是程序当前工作目录,这个路径可能会变
 - 序列化和反序列化的区别
 
- 序列化
 - 又叫做二进制格式化器,将对象转换成文本--字段、字段值、类名
 - Serialize(对象graph序列化到stream中)
 - 反序列化
 - 按照文本(字段、字段值、类名)信息里的类名,使用反射技术创建新对象,并将对一个的字段值设置到新的对象中
 - Deserialize(将对象从stream中反序列化,返回值为反序列化得到的对象)
 - Serializable特性
 
- 要序列化的类型必须标记为:[Serializable]
 - 该类型的父类也必须标记为:[Serializable]
 - 该类型中的所有成员的类型也必须标记为:[Serializable]
 - 序列化只会对类中的字段序列化(只能序列化一些状态信息)
 - 什么是委托?
 
- 就是一个能够存放与委托类具有相同签名方法的“方法集合”
 - 委托本质上就是一个类,继承与MulticastDelegate→Delegate(在Deleagate类中有一个IntPtr类)
 - 委托就是一个存放方法指针的容器,是一个安全的函数指针
 - 委托的目的是什么?
 
for(int j=0; j<nums.Length-1; j++)
{
for(int i=0;i<nums.Length-1-j;i++)
{
if(nums[i]>nums[i+1])
{
int temp=num[i];
nums[i]=nums[i+1];
nums[i+1]=temp;
}
}
}- 匿名方法是什么?
 
- 委托和事件没有可比性,因为委托是类型,事件是对象
 - 下面说的是委托的对象(用委托方式实现的事件)和(标准的event方式实现)事件的区别
 - 
- 事件的内部是用委托实现的,因为对于事件来说,外部只能“+=注册自己”、“-=注销自己”,外界不可以注销其他的注册者,外界不可以主动触发事件,因为如果Delegate就没法进行上面的控制,因为诞生事件这种语法,事件是用来阉割委托实例的,类比用一个自定义类阉割List。事件只能Add,Remove自己,不能赋值。事件只能+=、-=不能=
 
 
                    
                
                
            
        
浙公网安备 33010602011771号