zoukankan      html  css  js  c++  java
  • .Net的基础概念

    • 1,参数传递.

    默认都是按值传递(无论引用还是值类型),也就意味着传递参数的一个副本给方法.之后在方法体内对参数的更改,对原始参数没有影响.

    使用ref/out可以按引用传递,直接影响原始参数变量.两者的区别是ref参数必须在传递之前进行初始化.在异步方法和迭代器方法中,不能使用它.

    2,CTS,CLS

    CTS是一个集合,符合它的规范的类型才能在CLR上运行.CLS是它的子集,因为C#中有的类型,在VB中可能没有(ulong).

    默认不会进行CLS的检查,[assembly:System.CLSCompliant(true)]可以进行检查.

    不符合CLS的代码,在不同语言间会出现复用的问题.

    3,CLR

    编译阶段,生成的是CIL组成的中间语言,然后在运行时由个平台的JIT来编译成机器指令进行运行,所以能够跨平台.

    作用:1)管理内存(处理对象布局,管理对象引用,自动GC),2)线程执行,3)代码执行(可与非托管代码互操作,引用COM DLL),4)代码安全验证(取决于组件的来源)(以CTS验证Type),5)编译(CLR从不解释托管代码,由JIT编译代码),其可由高性能Server App承载并用托管代码编写逻辑.

    4,GC

    0代是新创建的对象,1代是经历过1次GC后留存的,2代是经历过1次以上GC留存的.回收时,先从0代开始.

    5,is/as

    • is.如果被判断对象是null,那么返回false.
    • as.如果类型不兼容,那么返回null.
    • 两者都不会抛出异常.但是as更加高效.

    6,接口/抽象类

    • 接口.不能含有Field和静态成员.可以作用于引用和值类型.
    • 抽象类.不能被new,不能sealed.实现其方法是用overriding.
    • "接口不变".当新增功能时,不能修改旧接口,而应该添加新的接口.接口应该设计为单一功能.
    • 当组件要被设计为多个版本时,是用抽象类.
    • 当功能要被使用在大范围的全异对象上时,使用接口.抽象类用于关系紧密的对象组.
    • 接口更适合于小而简练的功能.而抽象类可以有默认的实现.
    • 对于一个继承了多个接口的类,而多个接口中含有相同签名的方法,只需要实现一次即可.当需要分别实现时,必须显示指定,并且调用时需要类型转换.

    7,Attribute特性

    • 本质上是Class,为目标元素提供关联附加信息.在运行时通过反射来获取该附加信息,来动态改变代码的执行方式.
    • 主要用于序列化,编译器指令,设计模式上.
    • 其实例在编译时初始化.
    • 所有特性都继承自System.Attribute.必须有公用的构造器.特性还可以应用到其他特性上.

    8,Struct

    • 继承自System.ValueType(该类型为Ref类型),不具备多态性。
    • 值类型,存储在堆栈上.
    • 常用于存储数据。没有继承性。只能实现接口。
    • 只能定义带参构造器,不能有解析器,也不能有自定义无参构造(因为默认含有无参的Public构造).
    • 其可以不使用New初始化,但这样的话所有的字段都是未初始化状态,直到所有字段都完成初始化,否则引用它就会编译错误.
    • 可以重载Object的3个方法:Equals,ToString,GetHashTable.
    • struct变量使用完后,自动解除内存分配.
    • 用途:主要用于存储数据时,当数据量小时,结构数组有更高的效率,提供和非托管代码兼容性.

    9,CTS

    • 目的是创建一个跨语言的,类型安全,高性能代码执行的框架.定义各个语言必须遵守的规则,以使得使用不同语言建立的对象能够进行交互.
    • CTS定义了MSIL使用的预定义类型.所有的.NET编译器都是基于CTS实现的,因为所有的程序最后都要被编译成IL.
    • CLS是CTS的子集,定义了面向.NET的开发语言所必须支持的最小集合.
    • CIL,IL定义了与机器无关的虚拟指令.在执行时IL会被翻译成本地代码.
    • .Net Framework可以看做CIL在Win平台下的实现.

    10,参数

    • ref/out
      • 方法的定义和调用都需要有该keyword.否则编译错误.
      • 允许是否使用该keyword而带来的方法重载,而不能在两者之间进行.因为两者在编译后生成的IL代码是相同的.
      • ref传递的必须是一个初始化过的实际对象.
      • out可以接受null参数,但是在方法返回之前,必须进行赋值.同时,方法体内,会将外界赋给参数的值清空.
    • 按值/引用传递参数
      • 按值传递.引用类型传递的是该引用的值,即对象的地址.值类型传递的是该值的一个副本,所以修改参数的值不会影响原值.
      • 按引用传递.引用/值类型传递的都是引用/值的地址.

    11,委托

    • 存放着对方法引用的引用类型.
    • 可在全局范围内定义.
    • 应用了策略模式.把变化的部分封装起来.然后再把封装的对象作为一个对象传递给方法作为参数.
    • 实际上是一个类,可以使用new来实例化生成对象.定义了方法的类型.
    • 允许把方法当做另一方法的参数来传递.
    • 分离了方法的声明和方法的实现.
    • 把对方法的引用封装在委托对象中.
    • 调用时,用一个委托对象的变量来替代方法名称.
    • 内部继承关系:MultiDelegate->Delegate.
    • 字段:_target(方法所在类的对象,静态方法时为null)._MethodPtr(标识要调用的方法)._invocationList(委托链).
    • 委托链也是委托.可进行的操作是+=/-=.使用GetInvocationList()来获取委托链.
    • 事件就是一种委托链.

    Other

    • 枚举打印(toString)时,输出的是成员名称,而非1,2,3.
    • 类只能通过引用存储它的堆来访问.对引用赋值,只会创建引用的副本,而非实例的副本,然后所有的引用都指向同一存储区.
    • 可以使用Using来简化引用命名空间时的字符数.Using print= System.Consle.
    • 异常
      • 当没有Catch语句时,执行到Finally后停止,之后的代码会被忽略.
      • 有catch时,会执行完try-catch-finally,然后执行之后的代码.
      • throw Exception之后的代码不会被执行.
    • Box
      • 装箱是隐式发生的.
      • 而拆箱必须显式进行,并且类型要相同,兼容也不行.
    • 调用Windows API函数.

      • 引用System.Runtime.InterpServices;[DllImport(“XX”,Entry Point=”XXX”,CharSet=”XXXX”)]:XX为Dll所在的位置(User32.dll);XXX为所要引用的函数名,XXXX=UniCode/ANSI.

    • 继承
      • 子类使用new来覆盖父类的同名方法,然后再使用base.FunName()来调用被覆盖的父类方法.
    • 泛型
      • CLR允许值,引用,接口,委托的泛型,不支持枚举泛型.
      • CLR保证泛型并识别泛型的类型安全,并且不会产生拆箱,装箱动作.
      • 编译时T是一个占位符.实例化时根据不同的传入类型进行替换.
      • 不同的类型生成不同的代码(Class).各个类之间没有关系.
      • 静态变量在不同类型的Class之间不会共享.
      • 重载方法.在实例方法调用时检查(而非编译时).当一般方法与泛型方法签名相同时,一般方法优先.
      • 将泛型变量转换为另一类型为非法.除非另一类型兼容约束,可先转化为Object后在进行该转换;在没有约束类型为引用时,将泛型类型转化为NULL为非法.可指定默认值;与NULL比较,当无约束时可正常运行,但是当约束为Struct时,编译错误;未约束为引用时,对两个变量的比较为非法;不可将+,-*应用于非约束泛型类型上.
      • <T>类型参数(占位符);<int>类型实参.
      • 开放类型:含有<T>的;封闭类型:每个参数都是<int>的.只能构造封闭类型的instance.
      • ArrayList由于会产生装箱/拆箱操作,所以性能不如List<T>.
      • 类型推断
        • 在调用泛型方法时,自动判断所使用的类型.
        • 依据是变量的Type,而非引用的Type.所以是一种编译时行为.
      • 协变/逆变
        • 协变:子类到父类;逆变:父类到子类.
        • 仅泛型接口和委托支持,泛型类和方法不支持.
        • 原则:若一个几口需要对T支持协/逆变,则该接口所有的方法参数必须支持对T的协/逆变.
    • 迭代器
      • foreach可以用于任何实现了IEnumerator GetEnumerator()方法的类上,而不必非要实现IEnumerable接口.
      • 1  public IEnumerator<int> GetEnumerator()
        2         {
        3             int[] list = new int[]{1,2,3};
        4             foreach (int i in list)
        5                 yield return i;
        6         }
        GetEnumerator
      • yeild return 语句会使得Complier隐式生成一个实现了IEnumerable接口的内部类.
      • foreach的调用流程:GetEnumerator()->MoveNext()->return .Current.
      • 迭代器是延迟加载的,到in语句时才会调用.
    • If (o is Employee){Employee e = (Employee)o}两次转换;Employee e = o as Employee; If(e ! Null )一次,而且永不抛出异常.
    • Static常量直接嵌入IL内,无内存及地址,仅可为值类型(创建Type对象时创建,在类被夹在到AppDomain时创建).字段基于引用,ReadOnly(不可变的引用,而非不可变的对象)只可在构造器内为可写,其余只可读.不支持常量方法/参数.
    • 值类型[],New时会创建Obejct=0;引用类型[],New会创建引用,而无实际的元素对象.
    • 消息队列(MSMQ)
      • OS通信的基础(NT,2000以上),用于创建分布式,松散连接通信APP这些APP可通过不同种类的网络通信,亦可脱机.向断开连接的队列发送信息和有连接时一样.
      • 用户队列:公用MSMQ:在所有网络上复制传输,可被所有站点访问;专用MSMQ:仅在锁驻留的本地PC上可用(只能当知道完整Path或检查的APP访问),管理MSMQ:指定希望队列组件使用的管理的.响应MSMQ:目标APP接到消息返回给发送APP的相应信息.
      • 系统队列:日记:可选地存储,发送消息副本和删除信息;死信:存放无法传递或已过期的消息副本;专用系统:一系列系统执行处理操作所需的管理和通知消息的专用MSMQ.
      • 用途:1)数据库通过发送Message来操作数据(节省:对数据库连接请求数据的事件,从数据库返回数据的事件),当客户端不需要知道数据库操作结果时;2)ERP:断开连接时保存信息,连接恢复时发送消息,当队列驻留的PC无法工作,或者路由所需域控制器无法工作时消息无法投递,MSMQ可使消息暂存.
      • 由于消息传输时占用大量的带宽.所以应该尽量少使用.
    • 序列化
      • 可以利用序列化技术创建对象的深拷贝.
      • 必须保证序列化/反序列化时使用相同的formatter.
      • 可以将多个对象序列化到一个Stream中,然后以相同的顺序从Stream中反序列化出各个对象.
      • 序列化一个对象时,Type的全名和Assembly名会写入流中.
      • 反序列化时,使用Assembly.load方法加载Assembly.
      • 枚举和委托类型总是可序列化的.
      • 父类可序列化,子类必须显示声明才可以被序列化.
        • 子类为可序列化,而父类不可,那么结果亦是不可.
        • Object类是可序列化的.
        • 序列化会读取一个对象的所有字段(包括private).
        • 如果类型含有敏感信息,应该设置为不可序列化的.
      • [NoSerialized]标识不被序列化的属性.
      • [Seralizable]标识的属性不应使用自动属性,因为其名称不定.
    • JSON
      • 从结构上看,Data可分解为3个部分
        • Scalar标量.一个单独的字符串或者数字.
        • Sequence序列.有序的若干相关数据并在一起,即数组.
        • Mapping映射.名/值对.又称字典.
      • JOSN定义.
        • 逗号,并列的数据.
        • 冒号:映射.
        • 方括号[].并列数据的集合(数据).
        • 大括号{}.映射的集合(对象).
  • 相关阅读:
    Goahead在linux环境下安装部署
    vim卡住怎么办
    Clickhouse 实现 row number功能
    JavaScript ES6 模块化
    MySQL012事务的四个基本特征是什么
    MySQL015简述mysql中索引类型有哪些,以及对数据库的性能的影响
    MySQL010MySQL执行计划怎么看
    JavaScript ES6 Promise
    MySQL011如何处理MySQL的慢查询
    MySQL009MySQL为什么需要主从复制和读写分离
  • 原文地址:https://www.cnblogs.com/robyn/p/3729372.html
Copyright © 2011-2022 走看看