zoukankan      html  css  js  c++  java
  • C#高级

    程序集

    程序集概念:

    程序集是.net中的概念。

    .net中的dll与exe文件都是程序集。(exe与dll的区别(exe有程序主入口,可以执行,dll没有主入口,不可运行))

    程序集(Assembly),可以看做是一堆相关类打一个包,相当于java中的jar包(*)

    程序集的内容:

    程序集包含:

    类型元数据(描述在代码中定义的每一类型和成员,二进制形式)

    程序集元数据(程序集清单、版本号、名称等)

    IL代码(这些都被装在exe或dll中)

    资源文件

    每个程序集都有自己的名称、版本等信息。这些信息可以通过AssemblyInfo.cs文件来自己定义

    程序集的好处:

    程序中只引用必须的程序集,减小程序的尺寸。

    程序集可以封装一些代码,只提供必要的访问接口。

    添加程序集引用:

    添加路径、项目引用、GAC(全局程序集缓存)(了解)

    不能循环添加引用

    在c#中添加其他语言编写的dll文件的引用。(参考P/Invoke,在.net中调用非程序集的dll)

    反射

    反射:

    就是动态获取程序集中的元数据来操作类型

    反射中的一个重要的类(type):

    获取type的来那个中方法:

        通过类获得Type:Type t = typeof(Person)

    通过对象获得类的Type:Type t = p.GetType()

    Type类的一些常用验证方法:

            bool IsAssignableFrom(Type c):(直译:是否可以从c赋值)判断当前的类型的变量是不是可以接受c类型变量的赋值。

    bool IsInstanceOfType(object o):判断对象o是否是当前类的实例(当前类可以是o的类、父类、接口)

    bool IsSubclassOf(Type c):判断当前类是否是类c的子类。类的事,没有接口的事。

    IsAbstract,判断是否为抽象的,含接口

    关于Assembly的介绍:

    加载程序集方法:

        Assembly asm=Assembly.LoadFile(“c:abc.dll”);

    调用Assembly的GetExportedTypes方法可以得到Assembly中定义的所有的public类型

    调用Assembly的GetTypes()方法可以得到Assembly中定义的所有的类型

    调用Assembly的GetType(name)方法可以得到Assembly中定义的全名为name的类型信息

    动态创建对象:

    Activator.CreateInstance(Type t)会动态调用类的无参构造函数创建一个对象,返回值就是创建的对象,如果类没有无参构造函数就会报错

    GetConstructor(参数列表);//这个是找到带参数的构造函数

    动态调用的一些成员:

          MemberInfo类  抽象类,有很多子类,下面讲的类都继承自它,获取程序集成员的相关信息(类型、方法、事件、字段和属性)

    PropertyInfo 获取属性

    主要成员:CanRead、CanWrite、PropertyType属性类型;SetValue、GetValue:读取值,设置值,第一个参数是实例对象,因为set、get要针对具体实例,最后一个参数null。     pInfo.SetValue(p1, 30, null)

    MethodInfo  获取方法

    MethodInfo都是和具体对象不相关的,所以需要第一个参数指定要执行的对象。

    FieldInfo     获取字段

    EventInfo     获取事件

    反射若干场景(了解):

        1.插件机制,保证了程序的封装性,同时提高了程序的可扩展性。

    2.asp.net中根据用户访问的页面动态创建页面对象,比如访问Index.aspx,则根据访问的页面名称Index,通过反射动态创建该类型的对象。(在aspx页面中执行<%=System.Reflection.Assembly.GetExecutingAssembly().Location %>,查看dll中页面生成的的类名)

    3.数据访问层中使用工厂模式时,根据配置文件动态创建数据访问层对象。

    4.各种框架中,修改配置文件即可实现不同效果,都用到了反射。

    5.访问类中的私有成员

    6.各种需要动态创建类对象的场景都可以使用

    隐式类型:

        var关键字(在编译时已经能确定变量的类型了。并不是弱类型。)

    var i = 5;//int

    var j = 23.56;//double

    var k = "C Sharp";//string

    var x;//错误

    var y = null;//错误

    var z = { 1, 2, 3 };//错误  var z=new[] {1,2,3};//正确。

    var 强类型.根据后面的值自动推断类型,编译时把推断的类型替换掉var

    只是方便程序员使用而已。

    不能作为类成员的类型、不能用作方法的参数,返回值。(只能用作局部变量的类型推断)

    匿名类型:

        var p1 = new { Id = 1, Name = "YJingLee", Age = 22 };//属性也不需要申明

    var p2 = new { Id = 2, Name = "XieQing", Age = 25 };

    数组

    var intArray = new[] { 2, 3, 5, 6 };

    var strArray = new[] { "Hello", "World" };

    var objArray= new[] { new { Name = "YJingLee", Age = 22 }, new { Name = "XieQing", Age = 25 } };

    扩展方法:

          将扩展方法放到一个单独的类中,类声明为static(静态类),方法是静态方法,并且在第一个string上增加this。哇,string类“增加”扩展方法方法了,这只是假象,本质上仍然是静态方法,只不过C#提供了这样一个便利给大家,扩展方法内部不能调用被扩展类的私有、protected的东西。

    声明扩展方法的步骤:类必须是static,方法是static,第一个参数是被扩展的对象,前面标注this(this 数据类型 参数名)。使用扩展方法的时候必须保证扩展方法类已经在当前代码中using

    初始化器:

        对象初始化器

    Student stu= new Student(){ Id = 1, Name = "YJingLee", Age = 22 };

    更方便给对象赋值,在构造函数之后执行赋值,看IL代码。

    集合初始化器

    List<int> num = new List<int> (){ 0, 1, 2, 6, 7, 8, 9 };

    List< Student > stus= new List< Student >

    { new Student{Id=1,Name="YJingLee",Age=22},

    new Student{Id=2,Name="XieQing",Age=25}, };

    XML(可扩展标记语言)

    Xml语法特点:

    1. 严格区分大小写
    2. 有且只能有一个根节点
    3. 有开始标签必须有结束标签
    4. 属性必须使用双引号
    5. 没有预定义标签与html不一样
    6. 文档声明:<?xml version="1.0" encoding="utf-8"?>
    7. 注释:<!-- -->
    8. CDATA区:即原意文本-<![CDATA[…]]>
    9. 注意编码问题,文本文件实际编码要与文档声明中的编码一致。

    Xml读写(Dom XmlDocumnet demo):

    两种方式,推荐使用第二种:

    XmlDocument

    XDocument、(XElement、XAttribute

       XmlDocument xdoc=new XmlDocument();

        //文档声明

        xdoc.AppendChild(xdoc.CreateXmlDeclaration("1.0","utf-8",null));

        //添加根节点

        XmlElement xeroot=xdoc.CreateElement("Order");

           xdoc.AppendChild(xeroot);

          XmlElement xeCust =xdoc.CreateElment("CustomerName");

          xeCust.InnerText="老杨";

          xeroot.AppendChild(xeCust);

         XmlElement XeOrderName=xdoc.CreateElment("OrderName");

         xeorderName.InnerText ="bj200000";

          Xeroot.AppendChild(xeOrderName);

         XmlElement xeItem=xdoc.CreateElement("Items");

          xeroot.AppendChild(xeItem);

         

          XmlElement order1=xdoc.CreateElement("OrderItem");

           order1.SetAttribute("Name","电脑");

            order1.SetAttribute("Count",30); 

    Xpath简介:

    常用语法:

        /AAA  选择根元素AAA

        /AAA/CCC 选择AAA元素下的所有CCC子元素

        /AAA/BBB/CCC 选择AAA元素下子元素BBB下所有CCC字元素

        //BBB 选择所有BBB子元素

        //* 选择所有元素

        /AAA/BBB[1] 选择AAA下第一个BBB子元素

        //@id 选择所有有id属性的元素

        //BBB[@id] 选择有id属性的BBB元素

        //BBB[NOT(@*)] 选择没有属性的BBB元素

        //BBB[@id=’b1’] 选择id为b1的BBB元素

        //*[COUNT(BBB)=2] 选择含有两个BBB子元素的元素

        等等……..   用的时候可以查找

    深拷贝与浅拷贝

    深拷贝是把所有的数据都拷贝一份,包括引用都会拷贝,而浅拷贝只是把值类型拷贝一份,而引用类型则没有。

    图例:

       

          浅拷贝的实现(demo):

    /// <summary>

            /// 实现对象的浅拷贝

            /// </summary>

            /// <returns></returns>

            public Person QianKaoBei()

            {

                //MemberwiseClone()方法从object类中继承下来

                //作用就是把当前对象浅拷贝一份

                //浅拷贝当前对象

                return (Person)this.MemberwiseClone();

            }

          深拷贝(序列化实现):

    static object DeepCopy(object src)

            {

                BinaryFormatter Formatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.Clone));

                using (MemoryStream stream = new MemoryStream())

                {

                    Formatter.Serialize(stream, src);

                    stream.Position = 0;

                    return Formatter.Deserialize(stream);

                }

            }

    Attribute特性(attribute)

    是被指定给某一声明的一则附加的声明性信息

    就是一个标签,在使用当前类的地方,通过反射获取该特性

    Attribute就是类,Attribute类名一般都以Attribute结尾,使用的时候不用加Attribute这个结尾。使用Attribute的时候给的参数其实就是构造函数

    反编译DisplaynameAttribute,发现没有特殊代码。标签本身是没有含义,只是起到标注的作用,具体怎么解释、使用这个标识,是由使用者来决定:属性视图窗口、C#编译器。相当于在放上画一个“拆”,本身这个字没有含义。

    自定义特性(核心 反射):

          Attribute都从System. Attribute类继承,类名一般以Attribute结尾

    创建构造函数

    标记类的用途—AttributeUsage标记(标记的标记):AttributeTargets:可以添加到哪些成员上。AllowMultiple:是否允许在一个成员上标记这个Attribute的多个实例,默认false。标注在Attribute类的类名上方。

    Attribute只是给类、成员做标记,本身没有什么意义,不会发生任何动作,就像小偷踩点在门上做标记(StealableAttribute)一样,具体这个标记会起到什么作用是由使用这个类、成员的代码决定的。

    Property.GetCustomerAttribute()

  • 相关阅读:
    http基本概念和常见状态码
    JDK1.7 hashMap并发扩容死循环原理
    HashMap初始化数组原理,为什么是2的N次方?
    Rest接口加Http单向认证
    post和get乱码解决方法
    用迭代法实现二叉树的前、中、后序遍历
    搭建基于Zookeeper和solr的分布式搜索:solrcloud
    正向代理,反向代理及其作用
    二分查找向左或向右紧缩
    tcp四次挥手
  • 原文地址:https://www.cnblogs.com/reganLi/p/3401824.html
Copyright © 2011-2022 走看看