如鵬網學習筆記(三).Net進階技術

來源:互聯網
上載者:User

標籤:param   har   筆記   over   序列化   exception   get   中繼資料   組合   

 

net進階技術

一、多項目開發
1,添加對項目的引用
  //建立一個類庫,用來放公用的要使用的類,使用的時候別的項目去引用它
  //using 類庫檔案;

  注意事項:注意被引用的類要使用public修飾
  被引用的程式集中的類的修飾符,如果不寫的話,預設是internal。
  效果是,只有當前程式集(類庫)內部才能訪問。

2,多項目時候的設定檔的讀取問題
  a,只有主專案的設定檔才起作用(當前啟動的)
  b,config檔案不能改名,不能建多個config,在config裡面也不能建多個AppSettings段

3,在項目中“轉到定義”,是看不到原始碼的,可以使用反編譯工具查看

4,調用第三方dll(類庫檔案)的方法
  a,自己的項目就使用項目之間的引用方法
  b,使用別人寫好的dll就用:添加引用-瀏覽-選擇要添加的dll檔案


二、索引器 indexer
1,索引器:沒有名字,索引器的內部本質

2,可以是唯讀或者唯寫

3,為什麼字串只能char ch = s[5];不能s[5] = ‘a‘
  字串的不可變性;
  唯讀索引

  public char this[int index]{get;}


三、密閉類和靜態類

1,密閉類 sealed

   不能有子類。適用於系統中的基本類,比如String類。可以new對象

2,靜態類 聲明為 static

   沒法建立對象,沒法New;無法建立子類,只能聲明static成員(方法或者變數)
  適用於工具類,不需要new,直接調用它的靜態方法或者屬性

3,擴充方法
  使用方法:
  聲明一個靜態類,增加一個靜態方法,第一個參數是被擴充類型,標記為this,
  然後在其它類中可以直接調用,也可以使用普通靜態方法的方式調用,所以不能訪問private和protected成員。

四、深拷貝、淺拷貝
1,參考型別物件變數賦值的時候指向同一個對象

2,可以通過自訂一個拷貝方法賦值出來一個新的對象

3,如果對象之間有參考關聯性,如果拷貝的時候共用被引用的對象就是淺拷貝,如果被引用的對象也拷貝一份出來就是深拷貝

  拷貝一個對象的引用,叫淺拷貝。
  如果被引用的對象也拷被拷貝了,叫深拷貝

五、結構體 struct

  是實值型別,拷貝副本,不能繼承,一個結構不能從另一個結構或者類繼承。但是,結構從基類Object繼承

  struct Person
  {
    public int Age{get;set;}
    public String Name{get;set;}
  }

六、實值型別和參考型別
  兩者之間的區別:
  參考型別變數的賦值只複製對象的引用;參考型別在堆記憶體(malloc);

  實值型別變數賦值會拷貝一個副本;實值型別在棧記憶體;

  實值型別一定是sealed;


七、CTS,CLS,CLR,記憶體回收GC

  一般型別系統CTS,Common Type System

  通用語言規範CLS,Common Language Specification

  通用語言執行平台CLR,Common Language Runtime

  記憶體回收 GC, Garbage Collection

  1,.Net平台下不只有C#語言,還有VB.Net、F#等語言。IL是程式最終編譯的可以執行的二進位代碼(Managed 程式碼)
    不同的語言最終都編譯成標準的IL(中繼語言,MSIL);這樣C#就可以調用VB.Net寫的程式集(Assembly,dll、exe)
    在.Net平台下:不同語言之間可以互聯互連、互相調用

  2,不同語言中的資料類型各不相同,比如整數類型在VB.Net中是Integer、C#中是int。
    .Net平台規定了通用資料類型(CTS,Common Type System),各個語言編譯器把自己語言的類型翻譯成CTS中的類型。
    int是C#中的類型,Int32是CTS中的類型;int是C#中的關鍵字,但Int32不是

  3,不同語言的文法不一樣,比如定義一個類A繼承自B的C#文法是class A:B{},VB.Net的文法是Class A Inherits B。
    .Net平台規定了通用語言規範(CLS, Common Language Specification )

  4,IL代碼由通用語言執行平台(CLR, Common Language Runtime )驅動運行,
    CLR提供了記憶體回收
    (GC, Garbage Collection,沒有任何引用的對象可以被自動回收,分析什麼時候可以被回收)、JIT(即時編譯器);

  5,實值型別是放在“棧記憶體”中,參考型別放到“堆記憶體”,棧記憶體會在方法結束後自動釋放,“堆記憶體”則需要GC來回收

八、裝箱和拆箱

  實值型別賦值給Object類型變數的時候,會發生裝箱:封裝成Object

  Object類型變數賦值給實值型別的時候會發生拆箱,需要做顯示轉換。

  int i = 10;//實值型別賦值
  object obj = i;//裝箱,不需要進行顯示轉換,屬於隱式轉換
  int j = obj;//這裡報錯,發生拆箱,需要進行顯示轉換 //int j = (int)obj;

  注意:在拆箱的時候一定要顯示轉換回裝箱時候的資料類型,否則會報錯!!

九、比較相等的問題

  1,查看兩個對象是否是同一個對象:對象1.RefrenceEquals(對象2);

  2,String對象的==方法只是比較內容!

  3,Object的Equals方法也比較兩個變數指向的是否是同一個對象;對象如果override了Equals方法,就可以進行內容的相同比較

  4,預設情況下==不是調用Equals方法,需要重載==運算子

  5,String等這些類是重寫了Equals方法

十、字串緩衝池

  1,因為字串的不可變性,字串一旦被聲明,就會一直存在,直到GC判斷為未使用對象,被回收

  2,字串是參考型別,程式中會存在大量的字串對象,會浪費記憶體、導致效能低下,

  因此CLR提供了“字串緩衝池”,如果發現同樣內容的字串對象,再聲明時,直接拿來原來的對象
  (對字串對象進行了重用)

    string s1 = "rupeng";
    string s2 = "rupeng";
    string s3 = "ru" + "peng";
    string s4 = new string(s1.ToCharArray());
    string s5 = new string(new char[]{‘r‘,‘u‘,‘p‘,‘e‘,‘n‘,‘g‘});
    Console.WriteLine(Object.ReferenceEquals(s1,s2));//true,字串緩衝池的作用,兩個字串引用指向同一個對象
    Console.WriteLine(Object.ReferenceEquals(s1, s3));//true,編譯器最佳化,先進行拼接,後進行賦值
    Console.WriteLine(Object.ReferenceEquals(s1, s4));//false
    Console.WriteLine(Object.ReferenceEquals(s1, s5));//false
    Console.WriteLine(Object.ReferenceEquals(s4, s5));//false

十一、ref和out

  ref 方法參數的修飾符
  1,方法內部修改外部變數的指向;

  2,變數傳入前必須被賦值;

  3,在方法中不是必須被賦值;

  out 方法參數的修飾符

  1,方法需要多個傳回值的時候使用

  2,變數傳入前不用被賦值,賦值也沒用

  3,在方法中必須對參數進行賦值

十二、委託

  1,委託是一種資料類型,指向一個方法;委託是參考型別,變數可以是null

  2,聲明委託的方式:

    delegate 傳回值類型 委託名(參數1,參數2,。。。);比如:delegate void MyDel(int n)

    注意:這裡除了前面的delegate,剩下部分和聲明一個函數一樣,但是MyDel不是函數名,而是委託類型名

  3,可以聲明一個變數,指向和它類型相容的方法

  4,如何建立委託類型的對象:

    MyDel sp = new MyDel(SayHello);
    注意:
    SayHello需要和MyDel的參數和傳回值一樣;
    sp這個委託變數就指向SayHello這個方法,不要寫成new MyDel(SayHello()),因為加上()就是調用方法了

  5,簡化的方法:

    MyDel sp = SayHello;//編譯器會給搞成new MyDel(SayHello)

    注意不要寫成MyDel sp = SayHello();

  6,委託的使用:

    委託變數之間是可以互相賦值的,就是一個傳遞指向方法的過程;

    sp()就是調用指向的方法,如果有參數就傳遞參數

    程式碼範例:
    public delegate void MyDel(int n);//第一步,聲明一個委託

    static void M1(int a)//定義一個方法,方法的參數和傳回值要和委託對應
    {
      Console.WriteLine("M1"+a);
    }

    MyDel d1 = new MyDel(M1);//聲明一個MyDel類型的變數,指向一個指向M1方法的對象
    //上面的代碼可以簡化成 MyDel d1 = M1;

    注意:委託是參考型別,可以為null,如果委託變數是null,那麼如果調用的話,就會拋出異常:NullReferenceException;

7,Func、Action

  .Net中內建兩個泛型委派Func和Action(在“物件瀏覽器”的mscorlib的System下),日常開發中基本不用自訂委託類型了

  Func是有傳回值的委託,Action是沒有傳回值的委託

8,匿名方法

  使用Delegate的時候很多時候沒有必要使用一個普通的方法,因為這個方法只有這個Delegate會用,並且只用一次,這個時候使用匿名方法最合適

  匿名方法就是沒有名字的方法

  範例程式碼:
    MyDelegate p = delegate(int s){s = 10;};

9,lambad運算式
  函數式編程,在EntityFramework編程中用的很多

  1,Action<int> a1 = delegate (int i){Console.Write(i);};

  2,可以簡化為:
    Action<int> a2 = (int i)=>{Console.Write(i);};//(=>讀作goes to)

  3,還可以省略參數類型(編譯器會自動根據委託類型推斷)
    Action<int> a3 = (i)=>{Console.Write(i);};

  4,如果只有一個參數還可以省略參數的小括弧(多個參數不行)
    Action<int> a4 = i=>{Console.Write(i);};

5,如果委託有傳回值,並且方法體只有一行代碼,這一行代碼還是傳回值,那麼久可以連方法的大括弧和return都省略

  原本的:Func<int,int,string> f1 = delegate (int i,int j){return "結果是"+(i+j);};

  簡化為:Func<int,int,string> f2 = (i,j) =>"結果是"+(i+j);

  普通匿名型別也是一樣用lambda運算式

6,委託深入

  集合常用擴充方法:

  Where(支援委託)、Select(支援委託)、Max、Min、OrderBy

  First(擷取第一個,如果沒有則異常)

  FirstOrDefault(擷取第一個,如果一個都沒有則返回預設值)

  Single(擷取唯一一個,如果沒有或者多個則異常)

  SingleOrDefault(擷取唯一一個,如果沒有則返回預設值,多個則異常)

  ToList、ToArray

7,委託的組合

  委派物件可以“+相加”,調用組合後的新委派物件會一次調用被組合取來的委託:MyDel m5 = m1+m2+m3;

  組合的委託必須是同一個委託類型

  委託的“-”則是從組合委託中把委託移除;

  委託如果有傳回值,則有一些特殊。委託的組合一般是給事件用的,用普通的委託的時候很少用

8,事件

  事件文法:event MyDelegate md1;

  加了event關鍵字實現事件機制的好處:用了event事件,不可以修改事件已經註冊的值;不可以冒充進行事件通知了。只能+=、-=

9,委託與事件總結

  委託的作用:
    佔位,在不知道將來要執行的方法的具體代碼時,可以先用一個委託變數來代替方法調用(委託的傳回值,參數列表要明確)。
    在實際調用之前,需要為委託賦值,否則為null

  事件的作用:
    事件的作用與委託變數一樣,只是功能上比委託變數有更多的限制。
  比如:
    1,只能通過+=或-=來Binder 方法(事件處理常式)
    2,只能在類內部調用(觸發)事件

  (面試題)事件和委託的關係:事件由一個私人的委託變數和add_***和remove_***方法組成

  事件的非簡化寫法:聲明一個私人的委託變數和add、remove方法

10,委託和事件的區別和關係

  錯誤的說法“事件是一種特殊的委託”

  委託用的比較多,事件只有開發WinForm、WPF的時候用的才比較多

  事件、索引器、屬性本質上都是方法。

  (面試題)介面中可以定義什嗎?

  介面中只可以定義方法。介面中可以定義“事件、索引器、屬性”,因為他們本質上也都是方法。

十三、反射

  1,反射的作用:動態建立對象、動態賦值、動態調用方法

  2,反射簡介

    1,.Net中的類都被編譯成IL,反射就可以在運行時獲得類的資訊(有哪些方法、欄位、建構函式、父類是什麼等等),
    還可以動態建立對象、調用成員

    2,每個類對應一個Type對象,每個方法對應一個MethodInfo對象,每個屬性對應一個PropertyInfo……。
    這些就是類、方法、屬性的“中繼資料”(meta data)。
    對象和這個類的對象沒有直接關係。
    這些“中繼資料對象”和成員有關,和對象無關,也就是每個成員對應一個對象。

  3,類別中繼資料Type

    1,使用寫好的Person類
      1,擷取類資訊對象Type的方法:
        從對象擷取:Type type = person.getType();
        從類名擷取:Type type =typeof(Person); (type 是關鍵字,不是方法)
        從全類名(命名空間+類名)擷取:Type type = Type.GetType("com.rupeng.Person");

      2,為什麼要有這麼多擷取方式?
        主要根據要查詢的內容一樣,方式也就不一樣。
        如果有一個對象,就用getType()。
        如果沒有對象就可以用typeof;
        如果要運行時通過設定檔等拿到的字串來擷取就要用Type.GetType("com.rupeng.Person");

      3,Activator.CreateInstance(type)
        //使用無參數構造方法建立此類的對象(如果沒有無參建構函式會報異常)。
        要求類必須有無參建構函式。 相當於new Person() 是閑的蛋疼嗎?
    2,父類中GetType()返回的是什嗎?this代表“當前對象”,不是“當前類”

    3,Type的成員方法

      1,IsInterface、IsArray、IsPrimitive、 IsEnum:是否介面、數組、原始類型、枚舉等。

      2,String Name得到類名(不包含命名空間);String FullName包含命名空間

      3,BaseType得到父類的Type。

  4,Type的成員
    1,建構函式
      ConstructorInfo GetConstructor(Type[] types)//擷取參數類型匹配的建構函式
      ConstructorInfo[] GetConstructors()//獲得所有的public建構函式,包括父類的
      調用object Invoke(object[] parameters)可以調用建構函式

    2,方法
      MethodInfo GetMethod(string name, Type[] types)
      MethodInfo[] GetMethods() //獲得所有的public方法
      調用object Invoke(object obj, object[] parameters)可以調用方法

    3,屬性
      PropertyInfo GetProperty(string name) 擷取某個屬性
      PropertyInfo[] GetProperties() 擷取所有屬性
      PropertyInfo的主要成員:
      CanRead、 CanWrite是否可讀寫; GetValue、 SetValue讀寫值(第一個參數是要在哪個對象要調用)

    4,常用的Attribute(特性)
      [Obsolete] 表名此成員已淘汰

      當使用PropertyGrid的時候可以修飾屬性
      [ReadOnly(true)]在編輯器中唯讀,代碼賦值不受影響;
      [DisplayName("姓名")] 屬性的顯示名;
      [Browsable(false)]屬性是否可見

      1,Attribute文法
        Attribute用來在代碼中附加一些元資訊,這些原資訊可被編譯器,.NetFramework,或者我們的程式使用。
        方法、屬性、類上都可以標註Attribute

        一般起到說明、配置的作用;命名一般以Attribute結尾,如果以Attribute結尾的話使用的時候可以省略Attribute

        註解不會直接影響代碼的實際邏輯,僅僅起到輔助性作用;如果起作用也是編譯器、.NetFramework、程式去解析的

        在Type、MethodInfo、PropertyInfo等上都可以調用object[] GetCustomAttributes(Type attributeType,bool inherit)擷取標註的註解對象
        因為同一個Attribute可能標註多次,所以傳回值是數組


十四、Regex

  1,Regex是對字串進行匹配的文法,用來判斷一個字串是否符合某個規則

  2,基本元字元:

    a,. 表示除了\n以外的任意的單個字元

    b,[0-9]表示的是0-9之間的任意一個整數數字;[a-z]任意一個小寫字母;[A-Z]任意一個大寫字母

    c,\d表示數字,\D表示非數字,\s表示空白,\S表示非空白,\w表示小寫字母或數字和漢字
      \W表示特殊符號

    d,\ 表示對於 . 等特殊字元轉義

    e,()提升優先順序別和提取組

    f,[]代表一個區間中的任意一個:[abc\d]就代表abc或者數字中的任意一個字元

    g,| 代表或者

    h,+ 是出現1次或者無限次

    i,* 是出現0次或者無限次

    j,? 是出現0次或者1次

    k,{5}出現5次,{1,2}出現一次或者兩次,{5,8}出現5次至8次,

      {1,}最少出現1次,{3,}最少出現3次
    l,^ 以。。開始;$以。。結束

    使用Regex.isMatch("目標字串",@"Regex");//傳回值是bool類型

    提取://使用()進行分組,然後調用match.Groups[0].Value進行取值
      Match match = Regex.Match("2016-12-29", @"^(\d{4})\-(\d{1,2})\-(\d{1,2})$");

    範例程式碼:

      Console.WriteLine( Regex.IsMatch("2016-12-29", @"^\d{4}\-\d{1,2}\-\d{1,2}$") );

      Match match = Regex.Match("2016-12-29", @"^(\d{4})\-(\d{1,2})\-(\d{1,2})$");
      if (match.Success)
      {
        string year = match.Groups[0].Value;
        string month = match.Groups[1].Value;
        string day = match.Groups[2].Value;
        Console.WriteLine("年"+year+"月"+month+"日"+day);
      }
      else
      {
        Console.WriteLine("匹配不成功");
      }
      Console.ReadKey();

十五、對象的序列化

    對象序列化是將對象轉換成為位元據(位元組流),還原序列化是將其還原為對象。

    用處,避免程式重啟等情況造成的資料丟失,不僅程式重啟、作業系統重啟會造成對象的消失,就連退出函數範圍等都可能造成對象的消失

    序列化和還原序列化就是為了保持對象的持久化

    注意:一個對象想能序列化,必須標註成[Serializable],其父類和相關的欄位、屬性都要標記成“可序列化”

    序列化只會對類中的欄位序列化(只序列化一些狀態資訊)

    類結構改變後,之前序列化的內容盡量不用,否則可能會出錯!

    使用:
      BinaryFormatter類有兩個方法:
      void Serialize(Stream stream, object pbj)

      對象obj序列化到Stream中
      object Deserialize(Stream stream)
      將對象從stream中還原序列化,傳回值為還原序列化得到的對象

    為什麼要序列化:
      保持對象的持久化,將一個複雜的對象轉換流,方便我們的儲存與資訊交換

    應用:
      Asp.net中進程外Session要求對象可序列化
      還有Xml序列化,應用開發中Json序列化已經代替了二進位序列化和Xml序列化等


十六、XML(可延伸標記語言 (XML))

  1,XML優點:
    容易讀懂;格式標準任何語言都內建了XML分析引擎,不用單獨進行檔案分析引擎的編寫

  2,是一種格式化的方式來儲存資料,可以用記事本、瀏覽器開啟

  3,.Net程式中的一些設定檔app.config、web.config檔案都是xml檔案

  4,文法規範:
    標籤/節點(Tag/Node)、嵌套(Nest)、屬性。標籤要閉合,屬性值要用“”包圍,標籤可以互相嵌套

    XML樹,父節點、子節點、兄弟節點(siblings)

    xml編寫完成以後可以用瀏覽器來查看,如果寫錯了瀏覽器會提示。如果明明沒錯,瀏覽器還是提示錯誤,則可能是檔案編碼問題。

  5,文法特點:
    嚴格區分大小寫;

    有且只有一個根節點

    有開始標籤必須有結束標籤,除非自閉和(沒有內容的時候)<Person/>

    屬性必須使用雙引號
      (可寫可不寫,寫了檔案類型的時候要注意實際儲存的檔案類型需要一致)

    文檔聲明:
      <?xml version="1.0" encodeing="utf-8"?>

    注釋:

      <!--要注釋的內容-->


  6,注意編碼問題,文字檔實際編碼與文檔聲明中的編碼一致

  7,讀取xml檔案:
    <Person>
      <Student StuID="11">
        <StuName>張三</StuName>
      </Student>
      <Student StuID="22">
        <StuName>李四</StuName>
      </Student>
    </Person>


    XmlDocument doc = new XmlDocument();//建立一個讀取器對象
    doc.Load(@"xml檔案的路徑");//載入xml檔案
    XmlNodeList students = doc.DocumentElement.ChildNodes;//拿到xml檔案的節點集合
    foreach(XmlNode stu int students)
    {
      XmlElement element = (XmlElement)stu;
      string stuId = element.GetAttribute("StuID");
      XmlNode nameNode = element.SelectSingleNode("StuName");//擷取Person接線的Name
      string name = nameNode.innerText;
      Console.WriteLine(stuId+","+name);
    }

  8,產生XML檔案

    XmlDocument doc = new XmlDocument();//建立XML檔案對象
    XmlElement ePersons = doc.CreateElement("Persons");//建立根節點對象
    doc.AppendChild(ePersons);//將根節點對象添加到XML檔案對象
    foreach(Person person in ePersons)
    {
      XmlElement ePerson = doc.CreateElement("Person");
      ePerson.SetAttribute("id",person.id.ToString());
      XmlElement eName = doc.CreateElement("Name");
      eName.InnerText = person.Name;
      XmlElement eAge = doc.CreateElement("Age");
      eAge.InnerText = person.Age.ToString();

      ePerson.AppendChild(eName);//給ePerson添加子節點eName
      ePerson.AppendChild(eAge);//給ePerson添加子節點eAge
      ePersons.AppendChild(ePerson);//將ePerson添加給根節點
    }
    doc.Save("檔案全路徑");



    class Person
    {
      public Person(int id, string name, int age)
      {
        this.Id = id;
        this.Name = name;
        this.Age = age;
      }
      public int Id { set; get; }
      public string Name { set; get; }
      public int Age { set; get; }
    }

    Person[] persons = { new Person(1, "rupeng", 8), new Person(2, "baidu", 6) };

 

如鵬網學習筆記(三).Net進階技術

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.