C#高级编程笔记


CRL:公共语言运行库 或者 .net运行库,是.net framework的核心
IL(Intermediate Language):中间语言,Microsoft Intermediate Language,MSIL 微软中间语言
JIT编辑: Just In Time Compilation 及时编辑

在.net中,编译分为两个阶段:
    1)将源代码编译为微软中间语言
    2)CRL将IL编译为平台专用的代码

类型判断使用var关键字,编译器根据变量的初始值推断变量的类型

预定义数据类型:值类型,引用类型(string,Object)
值类型存储在堆栈中,引用类型存储在托管堆上 

C#转义字符:"C:\\Report\\image.cs" 等价于  @"C:\Report\image.cs"

枚举是用户定义的整数类型

C#预处理器指令:
#if  #else #endif  #error #warning #region #endregion

#if DEBUG
    console.WriteLine("x is :"+x);
#endif


可选参数:
    必须为可选参数提供默认值,可选参数还必须是方法定义的最后一个参数
    
方法重载:
    方法名称相同,但是参数个数不同或类型不同的方法

属性
    public string Name
    {
        get{return _name;}  
        private set{_name=value;}
    }
    public int Age{get;private set;}


   结构:结构是值类型不支持继承,派生自System.ValueType
    struct Test{ public string length;public}
    //合法,结构是值类型分配在堆栈上,声明的时候就在栈中分配空间
    //如果Test是一个类就会报错,因为test是未初始化的引用,不指向任何地方的一个地址
    Test test; test.length=5;
    
    结构适用于小的数据结构,当作为参数传递或者把一个结构赋予另一个结构时,
    结构的所有内容都被复制(对于类,只复制引用),容易造成性能损失
    
Object类 
所有的.net类都派生自System.Object,如果定义类的时候没有指定基类,编译器会自动假定这个类派生自Object.
System.Object()方法
ToString():为虚方法,可以在自己定义的类中重写   public override string ToString(){.....}
 GetHashCOde()   Equals()   Finalize()  GetType()  MenberwiseClone()浅复制
    
虚方法
把一个基类函数声明为virtual,就可以在任何派生类中重写该函数:
    Class MyBaseClass
    {
        public virtual string VirtalMethod()
        {
            return "this method is virtual and defined in MyBaseClass";
        }
    }
    
泛型 
    System.Collections   System.Collections.Generic
    从值类型转化成引用类型称为装箱
    List<T>
        var list=new List<int>();
        var stringList=new List<string>();
        var classList=new List<MyClass>();
        classList.Add(new MyClass());
    
    语法糖:指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。
            通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。
    yield是C#的一个语法糖.
    如果在语句中使用yield关键字,意味着它出现的方法、运算符或get访问器是迭代器。通过使用yield定义
    迭代器,可在实现自定义集合类型的IEnumerable和IEnumberator模式时无需其他显式类
    
    IEnumerable<T>派生自IEnumerable

    协变、抗变(逆变):
    所谓的协变,可以理解成:父类 -> 子类。父类的对象用子类替换,也可以理解成子类当父类用。
    所谓的抗变,可以理解成:子类 -> 父类。子类的对象用父类替换,也可以理解成父类当子类用。
    如果泛型类型用out关键字标注,泛型接口就是协变的。这也意味着返回类型只能是T
    如果泛型类型用in关键字标注,泛型接口就是抗变的。这样,接口只能把泛型类型T用作其方法的输入
    
元组:数组合并了相同类型的对象,元组合并了不同类型的对象

可空类型  long?
类型转换:只能从较小的整数类型隐式转换为较大的整数类型,不能从较大的整数烈性隐式转换为较小的整数类型
long.Parse(string)    int.Parse(string)    short.Parse(string)  .....

委托:
    把方法传递给其它方法时,需要用到委托。
    委托是一种特殊类型的对象,以前定义的所有对象都包含数据,委托包含的只是一个或多个方法的地址。
    委托的运用和类类似,先定义委托,再创建一个或多个委托的实例
    1)定义委托
    委托为方法的签名和返回类型指定名称
    委托语法类似于方法的定义,但没有方法体,定义的前面要加上关键字delegate
    ex:定义一个委托,该委托表示的方法包含两个long 型的参数,返回类型为double
        delegate double TwoLongsOp(long first,long second)
    2)使用委托
        C#中,委托的构造函数不能为空,委托在语法上总是接收一个参数的构造函数,这个参数就是委托引用的方法,这个方法必须匹配最初定义委托时的签名
        
    泛型Action<T>委托和Func<T>委托系统定义的两个泛型委托。
        Action<T>委托表示引用一个返回类型为Void的方法。这个委托存在不同的变体,可以传递之多16个不同的参数类型。
        同时,没有泛型参数的Action类可以调用没有参数的方法。例如,Action<in T>表示有一个输入参数的方法,Action<in T1,in T2>表示有两个输入参数的方法。

        Func<T>可以以类似的方法使用。不过Func<T>允许调用带返回参数的方法。Func<T>也有不同的变体,之多可以传递16个参数和一个返回类型。
        例如:Func<out TResult>委托类型可以无参的带返回类型的方法,Func<in T1,inT2,out Tresult>表示带两个参数和一个返回类型的方法。

        需要记住一个东西,Action<T>中的T可以有多个,但这些T类型都表示不同的输入类型。Func<T>可以表示带输出的方法,T可以有多个,
        且只有最后一个表示输出即最后一个是返回类型。Func<in T1,inT2,out Tresult>中的字符in、out在实际代码中是不会出现的。在VS中,可以通过IntelliSense查看

        比较一下,其实泛型委托和自定义的委托在使用上没什么不同。只不过泛型委托Func<T>系统已经为我们定义好了,直接使用就可以了,
        不需要再进行这样的定义delegate double DoubleOp(double x);。另一个泛型委托Action <T>的使用也是一样的,只不过不能有返回类型而已。
    
    多播委托,按顺序调用多个方法,此时委托的签名必须是void,否则只能得到委托调用的最后一个方法的结果
        +=  -+
    lambda表达式:只要有委托参数类型的地方,都可以使用lambda表达式
            string mid = ",middle part,";
            Func<string, string> lambda = para =>
             {
                 para += mid;
                 para += " and this was added to the string.";
                 return para;
             };
            Console.WriteLine(lambda("Hello word!"));
    
    事件:本质上是一个委托链。在使用事件的时候,必须要声明对应的委托,而触发事件,其实就是在使用委托链
        事件发布者、事件订阅者(发布者可对应多个订阅者,1:n)
        事件发布者对象中定义委托,以及委托类型的事件,发布事件的方法。
        事件订阅者中定义委托方法。
        
        应用中,事件订阅者需要在发布者对象中注册(即为发布者对象事件添加委托实例),然后调用
        发布者对象中触发事件的方法,即调用订阅者方法。
        (经典案例:裁判枪声响起,运动员开始跑步。)
        
在C#的event中,委托充当了抽象的Observer接口,而提供事件的对象充当了目标对象。委托是比抽象Observer接口更为松耦合的设计。
     .Net Framework的编码规范:
        一、委托类型的名称都应该以EventHandler结束。     handler:处理器
        二、委托的原型定义:有一个void返回值,并接受两个输入参数:一个Object 类型,一个 EventArgs类型(或继承自EventArgs)。 
        三、事件的命名为 委托去掉 EventHandler之后剩余的部分。 
        四、继承自EventArgs的类型应该以EventArgs结尾。
        
        
    
    
观察者模式:也被称为发布-订阅(Publish/Subscribe)模式,它属于行为型模式的一种。观察者模式定义了一种一对多的依赖关系,
            一个主题对象可被多个观察者对象同时监听。当这个主题对象状态变化时,会通知所有观察者对象并作出相应处理逻辑。
    


System.String 是一个类,专门用于存储字符串    
StringBuilder类 两个属性:Length,Capacity  默认情况下Capacity比length大
    当需要操作很长的字符串,或者要对字符串进行非常频繁的操作时,应该使用StringBuilder,
    其余场合,用String比较方便。
    StringBuilder sb=new StringBuilder("hello word!");//初始化
    sb.Remove(0,sb.length);//删除从某位置开始某一长度的字符
    sb.Apend("Hello StringBuilder");//添加内荣
    sb.Clear();//清空
    sb.Length=111;//Length不是ReadOnly的,可修改
    sb.AppendLine("this is a new Line");//新建一行
    sb.ToString();//转换为string

正则表达式:专门用于字符串处理的语言。
    添加引用using System.Text.RegularExpressions;
    正则表达式生成器
    
集合:
    大多数集合类都可以在System.Collections和System.Collections.Generic名称空间中找到
    泛型集合位于System.Collections.Generic名称空间中
    
    泛型类List<T> 实现了IList,ICollection,IEnumerable,IList<T>,ICollection<T>,IEnumerable<T>
    
    List<T>的AddRange() 方法:一次给集合添加多个元素
        var racers=new List<Racer>(20){henry,Sam,KEtty};
        racers.Add(new Racer());//一次添加一个元素
        racers.AddRange(new Racer(),new Racer());//一次添加多个元素
        racers.Insert(index,new Racer());//在指定位置插入
              .RemoveAt(index);//
              .RemoveRange(index,count);//
              .indexOf();//
              .Find();
              .Sort();
              ....
    
     泛型类队列Queue:System.Collections.Queue类标识对象的先进先出集合,
        存储在Queue(队列)中的对象在一端插入,从另一端移除
        能对集合进行顺序处理,先进先出
        能接受null值,允许重复的元素
            Queue myQ = new Queue();//创建一个队列 
            myQ.Enqueue("The");//入队   Enqueue:将对象添加到 Queue 的结尾处。
            myQ.Enqueue("quick");
            myQ.Enqueue("brown");
            myQ.Enqueue("fox");
            myQ.Enqueue(null);//添加null 
            myQ.Enqueue("fox");//添加重复的元素 

            //Dequeue 移除并返回Queue第一个元素(队列第一个)
            Console.WriteLine("(Dequeue)\t{0}", myQ.Dequeue());
            
            //Peek 返回位于队列开始处的对象(第一个元素)
            Console.WriteLine("(Peek)   \t{0}", myQ.Peek());
            
            // 打印队列中的所有值 
            Console.Write("Queue values:");
            PrintValues(myQ);
            public static void PrintValues(IEnumerable myCollection)
            {
             foreach (Object obj in myCollection)
                Console.Write("    {0}", obj);
             Console.WriteLine();
            }

          默认值:public T GetDocument()
            {
                T doc =default(T)
            }
    
    栈:Stack<T>后进先出,和队列类似都实现IEnumerable<T> 和ICollection接口
    
    链表:LinkedList<T>是一个双向链表
          优点是将元素插入到列表中间位置时,只需要修改上一个元素的next引用以及下一个元素的previous引用。
                在List<T>中插入一个元素,需要移动钙元素后面的所有元素    
    
    有序列表:SortedList<TKey,TValue>  
            使用场景:需要机遇键对所需的集合排序
    
    字典:Dictionary<TKey,TValue>
    有序字段:SortedDictionary<TKey,TValue>
    
    集:包含不重复的元素的集合称为集(set)
        ISet<T>,创建合集、交集,获取超集,子集
    
    位数组:如果需要处理的数字有很多位,就可以使用BitArray和BitVector32
    
    并发集合:线程安全的集合类,防止多个线程以相互冲突的方式访问集合
    
    
ildasm工具    

Windows使用一个系统:虚拟寻址系统,该系统把程序可用的内存地址映射到硬件内存中的实际地址上,这些任        
        由Windows在后台管理。这些内存被称为虚拟地址空间,或虚拟内存,一般直接叫内存。内存中有一个区域称为栈。
     
栈指针:(是操作系统中维护的一个变量)指栈中下一个空闲存储单元的地址,栈是向下填充的,即从发高内存地址向低内存地址填充。
        当数据入栈后,栈指针就会随之调整,以始终指向下一个空闲存储单元。

托管堆(简称为堆):是内存中的另一块区域。

指针:unsafe关键字  语法: int * pValue;
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

猜你喜欢

转载自blog.csdn.net/weixin_40719943/article/details/83931004