c#必会知识点
内存分配: --对于值类型来说,一般创建在线程堆栈上,但并非所有的值类型都创建在线程的堆栈上,例如:作为 类的字段时,值类型作为实例成员的一部分也被创建在托管堆上; 装箱发生时,值类型字段也会拷贝在托管堆上 --对于分配在堆栈上的局部变量来说,操作系统维护着一个堆栈指针来指向下一个自由空间地址 并且堆栈的内存地址是由高位到低位向下填充的
关于内存的分配,首先应该了解分配在哪里的问题,CLR管理内存的区域,主要有三块:分别为: 1.线程的堆栈:用于分配值类型实例. 堆栈主要由操作系统管理,而不受垃圾回收器(GC)的控制 当值类型实例所在方法结束时,其内存空间自动释放,栈的执行效率高,但存储容量有限 2.GC堆,用于分配小对象实例. 如果引用类型对象的实例大小小于85000字节, 实例将被分配在GC堆上, 当有内存分配或者回收时,垃圾收集器可能会对GC堆进行压缩 3.LOH(Large Object Heap)堆,用于分配大对象实例.如果饮用类型对象的实例大小 不小于85000字节时 该实例将被分配到LOH堆上,而LOH堆不会被压缩,而且只在完全GC回收时被回收
关于实例创建有多个IL指令解析: 1.newobj:用于创建引用类型对象 2.ldstr :用于创建string类型对象 3.newarr:用于分配新的数组对象 4.box :在值类型转换为引用类型对象时,将值类型字段拷贝到托管堆上发生的内存分配(装箱 拆箱)
值类型 和引用类型的区别: 1.值类型通常被分配在栈上,除非它被创建在引用类型的内部(即类内部,跟随对象存储在堆上) 它的变量直接包含变量的实例,使用效率比较高, 使用完后,立即回收 赋值时进行赋值没创建一个同值的新对象 2.应用类型分配在托管堆上,引用类型的变量通常包含一个指向实例的指针,变量通过该指针来引用实例 使用完后,不是立即回收,等待垃圾回收器定时检查堆中是否有没被引用的对象,若有GC则对其进行回收释放资源 效率低,需要进行地址转换, 赋值是只是对原有对象地址的引用 3.值类型是值COPY, 引用类型是地址COPY.
一. ADO 和 ADO.NET的区别: 1.ADO使用OLE DB接口并基于微软的COM技术 ADO.NET拥有自己的ADO.NET接口并基于微软的.net体系架构 2.ado以 Recordset存储 ado.net则以 DataSet表示 3.Recordset看起来更像单表,如果让Recordset以多表方式表示 就必须在SQL中进行夺标连接. 反之,DataSet可以是多个表的集合 4.ADO 的运作是一种在线方式,这意味着不论是浏览或更新数据都必须是实时的。 5.ADO.NET则使用离线方式,在访问数据的时候ADO.NET会利用XML制作数据的一份幅本 6.ADO.NET的数据库连接也只有在这段时间需要在线。
二.new 关键字用法: 1) new 运算符 :用于创建对象和调用构造函数。 2) new 修饰符 :用于向基类成员隐藏继承成员。 3) new 约束 :用于在泛型声明中约束可能用作类型参数的参数的类型。 三.序列化与反序列化: 1.序列化: 序列化是将对象状态转换为可保持或传输的格式的过程。 2.与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和 传输数据。
四.可访问性级别有哪几种: 1) public 访问不受限制。 2) protected 在它的类中可访问并且可由派生类访问。。 3) internal 只有在同一程序集的文件中,内部类型或成员才是可访问的。 4) protected internal 同一个程序集中的所有类,以及所有程序集中的子类都可以访问。 5) private 私有成员只有在声明它们的类和结构体中才是可访问的。
五. class和struct的异同: 相同点: 1) 语法类似。 不同点: 1) class是引用类型,继承自System.Object类; struct是值类型,继承自System.ValueType类,因此不具多态性。但是注意,System.ValueType是个引用类型。 2) 从职能观点来看,class表现为行为; 而struct常用于存储数据。 3) class支持继承,可以继承自类和接口; 而struct没有继承性, struct不能从class继承,也不能作为class的基类,但struct支持接口继承。 4) 实例化时,class要使用new关键字; 而struct可以不使用new关键字 struct在声明时就进行了初始化过程,所有的成员变量均默认为0或null。 5) 类用class修饰符,结构使用struct修饰符声明创建
六.如何选择结构还是类 1) 堆栈的空间有限,对于大量的逻辑的对象,创建类要比创建结构好一些。 2) 结构表示如点、矩形和颜色这样的轻量对象。例如,如果声明一个含有 1000 个点对象 的数组,则将为引用每个对象分配附加的内存。在此情况下,结构的成本较低。 3) 在表现抽象和多级别的对象层次时,类是最好的选择。 4) 大多数情况下该类型只是一些数据时,结构时最佳的选择。
七.抽象类 与 接口 的区别: 抽象类 1) 抽象方法只作声明,而不包含实现,可以看成是没有实现体的虚方法。 2) 抽象类不能被实例化。 3) 抽象类可以但不是必须有抽象属性和抽象方法,但是一旦有了抽象方法,就一定要把这 个类声明为抽象类。 4) 具体派生类必须覆盖基类的抽象方法。 5) 抽象派生类可以覆盖基类的抽象方法,也可以不覆盖。如果不覆盖,则其具体派生类必 须覆盖它们。
接口 1) 接口不能被实例化。 2) 接口只能包含方法声明。 3) 接口的成员包括方法、属性、索引器、事件。 4) 接口中不能包含常量、字段(域)、构造函数、析构函数、静态成员。 5) 接口中的所有成员默认为public,因此接口中不能有private修饰符。 6) 派生类必须实现接口的所有成员。 7) 一个类可以直接实现多个接口,接口之间用逗号隔开。 8) 一个接口可以有多个父接口,实现该接口的类必须实现所有父接口中的所有成员。
抽象类和接口的异同: 相同点: 1) 都可以被继承。 2) 都不能被实例化。 3) 都可以包含方法声明。 4) 派生类必须实现未实现的方法。 区 别: 1) 抽象基类可以定义字段、属性、方法实现。接口只能定义属性、索引器、事件、和方法 声明,不能包含字段。 2) 抽象类是一个不完整的类,需要进一步细化,而接口是一个行为规范。微软的自定义接 口总是后带able字段,证明其是表述一类“我能做。。。”。 3) 接口可以被多重实现,抽象类只能被单一继承。 4) 抽象类更多的是定义在一系列紧密相关的类间,而接口大多数是关系疏松但都实现某一 功能的类中。 5) 抽象类是从一系列相关对象中抽象出来的概念, 因此反映的是事物的内部共性;接口 是为了满足外部调用而定义的一个功能约定, 因此反映的是事物的外部特性。 6) 接口基本上不具备继承的任何具体特点,它仅仅承诺了能够调用的方法。 7) 接口可以用于支持回调,而继承并不具备这个特点。 8) 抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法却默认为非虚的,当 然您也可以声明为虚的。 9) 如果抽象类实现接口,则可以把接口中方法映射到抽象类中作为抽象方法而不必实现, 而在抽象类的子类中实现接口中方法。
CLR:公共语言运行库 是一个运行时环境,它负责资源管理(内存分配和垃圾回收), 并保证应用和底层操作系统之间必要的分离
CTS:(Common Type System)通用系统类型 所有.net语言共享这一类型系统,实现他们之间无缝的互操作 该方案还提供了语言之间的继承性 CLS:(Common Language Specification)公共语言规范 可以保证C#组件与其他语言组件间的互操作性 托管代码 : 使用基于公共语言运行库CLR的语言编译器开发的代码称为 托管代码 托管代码的优点: 跨语言继承,跨语言异常处理,增强的安全性,版本控制盒部署支持, 简化的组件交互模型,调试和分析服务
(重点)委托: 1.委托可以看做 方法的集合,里面保存了方法的指针.但是它是类型安全的 2.委托是一种引用方法的类型 3.委托允许将方法作为参数进行传递 4.委托可用于定义回调方法.
在.net中,配件的意思: 程序集(中间语言MSIL, 元数据, 资源, 装配清单)
面向对象的基本原则之一--->实现低耦合 高内聚 多聚合 少继承 类与类之间的关系,通常以耦合度来描述,即表示类与类之间的依赖关系程度. 没有耦合关系的系统是根本不存在的,因为类与类,模块与模块,系统与系统之间或多或少 要发生相互交互,设计应力求将类与类之间的耦合关系降到最低.
可空类型数据: private bool? gender---可以用来包装一个值类型,编译成中间代码时就是:Nullable<bool> _pgender; 本质就是一个新的类(所以可以为null,只不过在其中包含了一个bool变量)