.Net基础知识点

  1. Main函数是什么?
  2. 在程序中使用Main函数有什么需要注意的地方?
  3. CLR是什么?
  4. 程序集是什么?
  5. 当运行一个程序集的时候,CLR做了什么事情?
  6. 值类型的默认值是什么?
  7. 声明一个变量时在内存中做了什么事情?
  8. 初始化一个变量的时候又在内存中做了什么事情?
  9. new关键字做的事情?
  10. 数组一旦创建后,能不能修改数组的长度?
  11. 如何声明一个多维数组?
  12. 如何获取多维数组的总长度?
  13. 如何声明一个交错数组?
  14. 交错数组的本质是什么?
  15. 为什么要有方法?
  16. 如何实现方法的重载?
  17. 引用参数(ref)和输出参数(out)的相同点与不同点?
  18. 在什么情况下使用引用参数(ref)和输出参数(out)?
  19. 可变参数与普通数组参数的区别?
  20. 面向对象的三大特征是什么?
  21. 类和对象的关系?
  22. 创建某一个类的对象的时候,在内存中做了什么事情?例如 Person p = new Person();
  23. 属性存在的目的是什么?
  24. 访问修饰符有哪些并分别每一个访问修饰符?
  25. 为什么要有构造函数呢?
  26. 什么是封装?
  27. 封装的目的是什么?
  28. 类的命名规则是什么?
  29. 什么是类型?
  30. this关键字在方法中使用时,它代表什么?
  31. 值类型变量的初始化(内存分配)?
  32. 继承的好处?
  33. 继承的单根性
  34. 继承的传递性
  35. 当存在继承关系的时候,在子类中如何访问父类的非私有成员?
  36. 什么是里氏替换原则?
  37. 子类与父类对象之间的转换?
  38. is 和 as 操作符的用处和区别?
  39. override可以重写哪些 "类型" 的方法?
  40. 什么是多态?
  41. 抽象方法只能定义在抽象类中吗?
  42. CLR什么时候加载类?
  43. 当存在继承关系的时候,创建子类对象的时候会不会创建父类对象呢?
  44. 如果子类和父类存在同名但没有重写关系的方法的时候,那么会调用哪个方法?
  45. 如果子类和父类存在同名且有重写关系的方法,那么会调用那个方法?
  46. 虚方法和抽象方法的相同点与不同点?
  47. 子类中的base关键字指向的是子类对象还是父类对象?
  48. 它本身的类型是子类类型还是父类类型呢?
  49. 为什么要有抽象类?
  50. 使用多态的好处是什么?
  51. 什么情况下的类不能被实例化?
  52. 什么情况下抽象类的子类不需要实现父类的抽象成员?
  53. 虚方法(虚拟成员)和抽象方法(抽象成员)能不能被私有化?
  54. 静态成员能不能被标记为virtual、override 或 abstract?
  55. 接口的命名规则?
  56. 什么是接口?
  57. 接口能包含的成员有哪些?
  58. 接口的访问权限修饰符只能是哪两种?
  59. 接口能不能实现接口?
  60. 如果一个抽象类继承了一个接口,那么将继承的方法设置为抽象方法,还是去实现该方法?
  61. 使用接口应注意什么事项?
  62. 显式接口和隐式接口?
  63. 接口与抽象类的区别?
  64. 转换分类?
  65. ToString()方法?
  66. Parse()和TryParse()方法的区别?
  67. 什么时候加载静态成员
  68. 什么时候用静态成员
  69. 在普通类和静态类中的区别
  70. 静态类的继承
  71. 类和成员的访问修饰符
  72. 结构本质是什么?
  73. 值类型和引用类型的选择
  74. new关键字的作用
  75. 类和结构的区别
  76. 值类型和引用类型作为参数传递的区别
  77. 访问级别约束
  78. 析构函数
  79. 为什么不能在结构体中定义析构函数
  80. 字符串常用方法
  81. ==运算符和Equals()方法的区别
  82. 字符串的恒定性
  83. StringBuilder 和 String 的区别?
  84. 枚举本质是什么?
  85. 枚举项的相关问题
  86. IEnumerable接口
  87. 集合
  88. 动态数组和 泛型集合的不同点和优缺点
  89. 泛型list的常用方法
  90. 哈希表内部机制原理
  91. 哈希表存取操作原理
  92. 泛型集合引用命名空间
  93. List 和ArrayList的性能比较
  94. 应该使用try语句块的情况
  95. Windows Form程序相关文件
  96. Path类相关方法
  97. 操作目录(Directory类)相关方法
  98. 操作文件(File)相关方法
  99. DirectoryInfo(文件夹的一个“类”,用来描述一个文件夹对象)相关方法
  100. using语句的本质
  101. 文件操作注意问题
  102. 序列化和反序列化的区别
  103. Serializable特性
  104. 什么是委托?
  105. 委托的目的是什么?
  106. 委托的适用情形?
  107. 冒泡排序?
  108. 匿名方法是什么?
  109. 多播委托是什么?
  110. 事件本质是什么?
  111. 委托和事件的区别是什么?
  • 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;
}

哈希表存取操作原理

  • 如何存?
    • 下标是根据key的hash值算出来的。当我们向Hashtable中Add元素时,元素储存在Hashtable的数组里的下标是根据添加key的hash值算出来的(但因为hash值取模数组长度,所以肯定不会超过当前数组长度)
    • 每个对象算出的Hashcode并不是唯一的,有可能出现多个对象的Hashcode相同
    • 解决机制
      • 再Hash一次
      • 桶装模式,将两个相同的Hashcode的对象装入一个位置
    • 当新增时,Hashtable里的容器数组已经满了,则以数组的两倍扩容
  • 如何取?
    • 当我们从Hashtable里取元素时(根据key来取),会根据key的hash值算出要取的元素的下标,并比较元素里的key和当前要找的key参数的hash值是否相等,同时还要比较两个key的引用是否一致,如果都满足,则确定找到要取的元素
  • 泛型集合引用命名空间
    • System.Collections.Generic
  • List 和ArrayList的性能比较
    • 避免装箱、拆箱操作带来的性能损耗
    • 在添加元素时随参数类型进行检查(编译时检查)
  • 应该使用try语句块的情况
    • 网络操作、文件操作、数据库操作、除法操作、强制类型转换操作
  • Windows Form程序相关文件
    • designer.cs 设计类和前台两个类是兄弟类的关系
  • Path类相关方法
    • 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(文件夹的一个“类”,用来描述一个文件夹对象)相关方法
    • GetParent(得到目录的父目录)
  • using语句的本质
    • 就是一个try finally
    • 所有要使用using关键字来释放资源的类都必须实现IDisposable接口
  • 文件操作注意问题
    • 当使用文件流的时候,在关闭流的时候数据才会保存到文件中
    • Close执行了Dispose()并回收对象
    • 所有要使用using关键字来释放资源的类都必须实现IDisposable接口
    • 获取当前exe文件执行的路径用(Assembly.GetExecutingAssembly().Location不要用Directory.GetCurrentDirectory(),因为获取的是程序当前工作目录,这个路径可能会变
  • 序列化和反序列化的区别
    • 序列化
      • 又叫做二进制格式化器,将对象转换成文本--字段、字段值、类名
      • Serialize(对象graph序列化到stream中)
    • 反序列化
      • 按照文本(字段、字段值、类名)信息里的类名,使用反射技术创建新对象,并将对一个的字段值设置到新的对象中
      • Deserialize(将对象从stream中反序列化,返回值为反序列化得到的对象)
  • Serializable特性
    • 要序列化的类型必须标记为:[Serializable]
    • 该类型的父类也必须标记为:[Serializable]
    • 该类型中的所有成员的类型也必须标记为:[Serializable]
    • 序列化只会对类中的字段序列化(只能序列化一些状态信息)
  • 什么是委托?
    • 就是一个能够存放与委托类具有相同签名方法的“方法集合”
    • 委托本质上就是一个类,继承与MulticastDelegate→Delegate(在Deleagate类中有一个IntPtr类)
    • 委托就是一个存放方法指针的容器,是一个安全的函数指针
  • 委托的目的是什么?
    • 能够将方法作为参数传递
    • (多播委托)调用一个委托,执行N个方法
  • 委托的适用情形?
    • 当方法传递的参数为一个方法时,就用委托
  • 冒泡排序?
    • 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;
      }
      }
      }
  • 匿名方法是什么?
    • 并不是真没有名字,它在CLR编译时会产生一个临时方法名
    • 匿名方法产生后,方法指针会存放在委托变量中,供程序调用
  • 多播委托是什么?
    • 可以向委托上注册多个方法
    • 也可以从委托上移除注册方法
    • 如果委托上注册了多个有返回值的方法,那么在调用之后委托返回的是最后一个方法的返回值
  • 事件本质是什么?
    • 本质就是提供一个Add和Remove方法的委托对象
    • 是为了约束一个委托对象的操作方法,对外只提供+=和-=操作
    • 观察者模式就是事件的体现
  • 委托和事件的区别是什么?
    • 委托和事件没有可比性,因为委托是类型,事件是对象
    • 下面说的是委托的对象(用委托方式实现的事件)和(标准的event方式实现)事件的区别
      • 事件的内部是用委托实现的,因为对于事件来说,外部只能“+=注册自己”、“-=注销自己”,外界不可以注销其他的注册者,外界不可以主动触发事件,因为如果Delegate就没法进行上面的控制,因为诞生事件这种语法,事件是用来阉割委托实例的,类比用一个自定义类阉割List。事件只能Add,Remove自己,不能赋值。事件只能+=、-=不能=
posted @ 2013-10-13 19:57  飞贼克斯  阅读(1180)  评论(4编辑  收藏  举报