亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

C#方法的總結詳解

2020-01-24 03:16:32
字體:
來源:轉載
供稿:網友
C#方法
1:實例構造器和類
2:實例構造器和結構
3:類型構造器
4:操作符重載方法
5:轉換操作符方法
6:擴展方法
7:部分方法
1:實例構造器和類
構造器是允許將類型的實例初始化為良好狀態的一種特殊方法,創建一個引用類型的實例時,先為實例的數據字段分配內存,然后初始化對象的附加字段(類型對象指針和同步索引),最后調用構造函數來設置對象的初始狀態。構造函數不能被繼承,所以不能被virtual、new、override、sealed和abstract修飾,若沒有顯示定義任何構造函數,編譯器將定義一個無參的public構造函數,但若是抽象類,編譯器將定義一個無參的protected的構造函數
創建一個類的實例并不一定非要調用構造函數。
1:使用Object的MemberwiseClone()方法。他的作用就是創建當前 System.Object 的淺表副本,內部工作機制是分配內存,初始化對象的附加字段(類型對象指針和同步索引),然后將源對象的字節數據復制到新對象中。從下面的代碼可以看出MemberwiseClone()實現了對象復制,而不是簡單的對象引用。
復制代碼 代碼如下:

class Program
    {
        public int X;
        static void Main(string[] args)
        {
            Program p = new Program();
            p.X = 1;
            Program q = (Program)p.MemberwiseClone();
            Program z = p;
            p.X = 2;
            Console.WriteLine("p.X=" + p.X);//輸出:p.X=2
            Console.WriteLine("q.X=" + q.X);//輸出:q.X=1
            Console.WriteLine("z.X=" + z.X);//輸出:z.X=2
            Console.Read();
        }
    }

2:反序列化。在網絡編程的時候,經常將一個對象序列化成二進制,然后傳輸出去,接收端反序列化成原來的對象,反序列化使用的是類
System.Runtime.Serialization.FormatterServices的方法public static object GetUninitializedObject(Type type)或
public static object GetSafeUninitializedObject(Type type)分配內存,而在這兩個方法內部沒有調用要被反序列化對象的構造函數。
字段的初始化代碼會被編譯器自動添加到相應的構造函數中,非靜態字段的初始化代碼會自動加到實例構造函數中,靜態字段的初始化代碼則添加到靜態構造函數中,如果你的代碼中有多個字段被初始化,還有多個構造函數的話,初始化代碼在每個構造函數中都會有一份,這無疑會讓你的生成文件(如DLL,EXE文件)變大。
證明這一點的代碼如下:
復制代碼 代碼如下:

public class SomeType
    {
        public  int x=1,y=2,z=3;
        public SomeType() { }
        public SomeType(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
        public SomeType(int x)
        {
            this.x = x;
        }
}
//經過IL反編譯,方法SomeType(int x, int y)代碼如下
.method public hidebysig specialname rtspecialname
        instance void  .ctor(int32 x,
                             int32 y) cil managed
{
  // 代碼大小       45 (0x2d)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.1
  IL_0002:  stfld      int32 MyTest.SomeType::x
  IL_0007:  ldarg.0
  IL_0008:  ldc.i4.2
  IL_0009:  stfld      int32 MyTest.SomeType::y
  IL_000e:  ldarg.0
  IL_000f:  ldc.i4.3
  IL_0010:  stfld      int32 MyTest.SomeType::z
  IL_0015:  ldarg.0
  IL_0016:  call       instance void [mscorlib]System.Object::.ctor()
  IL_001b:  nop
  IL_001c:  nop
  IL_001d:  ldarg.0
  IL_001e:  ldarg.1
  IL_001f:  stfld      int32 MyTest.SomeType::x
  IL_0024:  ldarg.0
  IL_0025:  ldarg.2
  IL_0026:  stfld      int32 MyTest.SomeType::y
  IL_002b:  nop
  IL_002c:  ret
} // end of method SomeType::.ctor

先執行了初始化代碼,其他構造函數都包含了初始化代碼,然后在執行構造函數中的賦值代碼,要解決這個代碼膨脹問題,方法很簡單,把初始化代碼寫在無參構造函數中,讓其他構造函數調用。
2:實例構造器和結構
值類型的工作方式與引用類型截然不同,值類型其實并不需要定義構造函數,地球人根本阻止不了值類型實例化,編譯器根本不會生產默認無參構造函數,如果你顯示聲明無參構造函數,編譯根本通過不了,報錯“結構不能包含顯式的無參數構造函數”。由于值類型存在棧中,根本不需要對堆中的數據進行引用,所以我們可以在定義的時候就直接賦值,(int i=0;string s=”a”;Point p;p.X=2;)他根本不需要new,new當然是可以的,調用構造函數會初始化所有的字段成相應類型的默認值,實例如下:
復制代碼 代碼如下:

public struct Point
    {
        public int x, y;
        //public Point() { }//錯:結構不能包含顯式的無參數構造函數
        //public int z = 4;//錯:結構中不能有實例字段初始值設定項
        //public Point(int x) //在控制返回調用方之前,字段“Point.y”必須被完全賦值,要解決這個問題就手動給y加一個默認值吧,
        //你也可以加this=new Point();將所有的字段的值初始化為0或null
        //{
        //    this.x = x;
        //}
        public void Test()
        {
            Point p;
            p.x = 1;
            p.y = 2;
            Console.WriteLine(p.x+","+p.y);//輸出1,2
        }
    }

結構的特點:
   1:不能顯示定義無參構造函數
   2:不能在定義字段的時候初始化
   3:聲明有參構造函數的時候,要初始化所有的字段
3:類型構造器
實例構造器就是靜態構造函數,他的作用是設置類型的初始化狀態,靜態構造函數只能有一個,且是無參的,不能有訪問修飾符修飾,默認就是private,由編譯器調用執行。實例如下:
復制代碼 代碼如下:

public class SomeType
    {
        public static int x = 520;
        static SomeType()
        {
            x = 112;
        }
    }

    //用.NET reflector查看源碼,如下
    public class SomeType
    {
        public static int x ;
        static SomeType()
        {
            x = 520;
            x = 0x70;
        }
        public SomeType() { }
    }

在定義靜態字段并初始化,編譯器會自動生成一個類型構造器(靜態構造函數),并將靜態字段的初始化代碼插在類型構造器的前面,從上面的代碼可以看出,定義時初始化和在類型構造器中初始化只需要一個即可,還有112的16進制為0x70,所以在代碼中看到16進制也不用大驚小怪,根本不涉及性能問題,若定義了靜態字段,但沒有初始化任何一個,編譯器是不會生成類型構造器的。但是靜態字段還是會被初始化,其實不管是靜態的還是非靜態的字段都是會被編譯器自動初始化的,int類型的初始化為0;bool:False;string:null,這就是為什么你在實例化實體的時候,有些字段你沒有初始化,卻不會報錯,而且你知道沒有初始化的字符串的值就是null,也就是說編譯器會幫你初始化你沒有初始化的字段,然而在方法中定義的局部變量是需要自己初始化的,如果你沒有初始化,會報一個錯誤“使用了未賦值的局部變量X”。
4:操作符重載方法
要想實現操作符重載,只需要保證以下兩點,其他的話都是浮云:
1:操作符重載方法必須是public和static方法
2:操作符重載方法至少有一個參數的類型與當前定義這個方法的類型相同。之所以是要這個條件是為了使編譯器在合理的時間內找到要綁定的操作方法
,實例如下
復制代碼 代碼如下:

public class Complex
    {
        public int data;
        public Complex(int data)
        {
            this.data = data;
        }
        public static Complex operator +(Complex c1, Complex c2)
        {
            return new Complex(c1.data+c2.data);
        }
        public void Test()
        {
            Complex c1 = new Complex(1);
            Complex c2 = new Complex(2);
            Complex c3 = c1 + c2;
            Console.WriteLine(c3.data);//輸出3
        }
    }

5:轉換操作符方法
要實現轉換操作符方法,條件和操作符重載方法的條件是一樣的,實例如下:
復制代碼 代碼如下:

public class Rational
    {
        public Rational(int data)
        {
            this.data = data;
        }
        public Rational(char data)
        {
            this.data = (int)data;
        }
        //隱式類型轉換:int->Rational
        public static implicit operator Rational(int data)
        {
            return new Rational(data);
        }
        //隱式類型轉換:char->Rational
        public static implicit operator Rational(char data)
        {
            return new Rational(data);
        }
        //顯示類型轉換 Rational->int
        public static explicit operator int(Rational val)
        {
            return val.data;
        }
        //顯示類型轉換 Rational->char
        public static explicit operator char(Rational val)
        {
            return Convert.ToChar(val.data);
        }
        public void Test()
        {
            Rational r1 = 1;//將int類型隱式轉換成Rational
            Rational r2 = '2';//將char類型隱式轉換成Rational
            int i = (int)r1;//將Rational類型顯示轉換成int
            char c = (char)r2;//將Rational類型顯示轉換成char
            Console.WriteLine("i=" + i);//輸出:i=1
            Console.WriteLine("c=" + c);//輸出:c=2
        }

        int data;
    }

隱式和顯示類型轉換的實現原理就這么簡單,在C++中隱式類型轉換根本不需要你寫代碼,只要有相應的public構造函數就可以了,如int轉換成Rational,只需要有構造函數public Rational(int data)就可以了,如Rational r=1;編譯器會盡一切努力尋找將int類型轉換成Rational的方法,當它發現這個構造函數,他說都不說就幫你進行轉換了,就因為這樣有時候非??拥阋粋€int類型無緣無故的就變成Rational了,而你卻根本不知道怎么回事,有時候為了解決這個問題,還得自己定義一個類(Uint)來封裝int,然后構造函數改成Rational(Uint data),C#就沒有這個問題,當然你要想實現隱式類型轉換就自己寫代碼吧。
6:擴展方法
實現擴展方法的條件:
1:定義擴展方法的類必須是非泛型靜態類
2:這個類必須有自己的作用域,即不能是內部類
3:方法必須是public和static
4:方法的第一個參數必須用this修飾,第一個參數就是你要擴展的類型,實例如下:
復制代碼 代碼如下:

public static class StringExtensions
    {
        public static int ToInt(this string s)
        {
            return Convert.ToInt32(s);
        }
        public void Test()
        {
            string s = "2";
            Console.WriteLine(s.ToInt());
        }
}

7:部分方法
你懂的
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩精品免费视频| 国产精品精品一区二区三区午夜版| 亚洲国产精久久久久久久| 欧美日韩国产91| 日产精品久久久一区二区福利| 在线看日韩欧美| 亚洲a∨日韩av高清在线观看| 136fldh精品导航福利| 国内精品在线一区| 日本成人精品在线| 欧美激情在线视频二区| 亚洲一区中文字幕在线观看| 欧美理论在线观看| 久久亚洲国产精品成人av秋霞| 欧美在线精品免播放器视频| 日韩天堂在线视频| www欧美xxxx| 92看片淫黄大片看国产片| 日韩av中文字幕在线播放| 国产日本欧美一区二区三区在线| 国产精品久久久久久av福利软件| 久久久精品亚洲| 国产在线精品一区免费香蕉| 国产精品青草久久久久福利99| 欧美黑人性生活视频| 亚洲人成在线观看网站高清| 亚洲第一精品久久忘忧草社区| 亚洲摸下面视频| 国产精品第七十二页| 亚洲国产日韩欧美在线图片| 久久艳片www.17c.com| 国产在线久久久| 深夜福利91大全| xxxxx91麻豆| 欧美最猛性xxxxx(亚洲精品)| 国产有码一区二区| 亚洲男人天堂2019| 成人www视频在线观看| 日韩动漫免费观看电视剧高清| 国产精品丝袜一区二区三区| 久久色精品视频| 亚洲成人三级在线| 日韩精品视频中文在线观看| 国产视频久久久久| 精品成人乱色一区二区| 日韩av电影在线免费播放| 欧美在线视频导航| 亚洲国产精品小视频| 亚洲va码欧洲m码| 少妇高潮久久久久久潘金莲| 福利一区视频在线观看| 成人国产精品一区| 国产一区二区欧美日韩| 日本道色综合久久影院| 成人动漫网站在线观看| 日韩免费观看av| 永久免费精品影视网站| 国产美女精品视频免费观看| 亚洲成年人影院在线| 欧美性xxxx在线播放| 欧美肥老妇视频| 国产视频精品自拍| 欧美一级在线亚洲天堂| 亚洲天堂男人天堂女人天堂| 成人日韩av在线| 国语自产精品视频在线看抢先版图片| 久久精品2019中文字幕| 91系列在线播放| 疯狂做受xxxx欧美肥白少妇| 国产精品视频久久| 丰满岳妇乱一区二区三区| 亚洲免费精彩视频| 久久久女人电视剧免费播放下载| 中文字幕精品一区二区精品| 狠狠色香婷婷久久亚洲精品| 亚洲一区二区福利| 欧美性xxxx极品hd满灌| 亚洲国产日韩欧美在线图片| 奇米4444一区二区三区| 国产精品91久久久久久| 国产成人亚洲综合| 久久精品电影网| 亚洲精品视频中文字幕| 亚洲一级片在线看| 欧美另类69精品久久久久9999| 韩剧1988在线观看免费完整版| 中文字幕亚洲一区在线观看| 日本欧美在线视频| 欧美成人黑人xx视频免费观看| 亚洲第一区在线观看| 国产丝袜高跟一区| 少妇激情综合网| 国产精品久久久久久久久久小说| 亚洲欧美中文日韩在线v日本| 另类天堂视频在线观看| 97在线看免费观看视频在线观看| 欧美视频免费在线观看| 欧美电影在线观看| 国产热re99久久6国产精品| 国产精品偷伦免费视频观看的| 欧美另类交人妖| 亚洲综合自拍一区| 午夜精品一区二区三区视频免费看| 亚洲欧美日韩综合| 亚洲成人精品久久久| 最近2019中文字幕mv免费看| 国产精品麻豆va在线播放| 欧美在线观看日本一区| 97视频免费在线看| 精品国产1区2区| 国产精品欧美一区二区| 亚洲美女自拍视频| 亚洲精品国产精品国自产观看浪潮| 久久精品视频中文字幕| 97在线观看免费高清| 欧美精品一区二区免费| 欧美在线不卡区| 91热精品视频| 日韩在线观看视频免费| 日韩电影在线观看永久视频免费网站| 日韩在线观看高清| 日韩二区三区在线| 69久久夜色精品国产69乱青草| 日韩av中文字幕在线免费观看| 国产精品∨欧美精品v日韩精品| 国产精品成人aaaaa网站| 日韩国产精品视频| 国产亚洲福利一区| 92国产精品久久久久首页| 国产精品久久婷婷六月丁香| 国产精品极品尤物在线观看| 91老司机精品视频| 欧美福利视频在线观看| 中文字幕亚洲精品| 精品亚洲一区二区三区在线观看| 国产精品美女呻吟| 国产精品久久久久aaaa九色| 亚洲国产精品久久91精品| 5278欧美一区二区三区| 亚洲国产天堂久久国产91| 国产亚洲精品综合一区91| 亚洲女人天堂视频| 精品香蕉一区二区三区| 91成人在线播放| 午夜精品福利在线观看| 日韩在线观看成人| 久久91亚洲精品中文字幕奶水| 亚洲电影免费观看高清| 国产精品丝袜久久久久久高清| 久久夜色精品亚洲噜噜国产mv| 美日韩精品免费视频| 亚洲国产精品久久| 日韩精品有码在线观看| 国产精品一区二区av影院萌芽| 精品国产一区二区三区四区在线观看| 日韩最新av在线| 亚洲欧美日韩在线一区| 亚洲精品动漫久久久久| 亚洲自拍中文字幕| 亚洲成avwww人| 日韩一区二区久久久| 亚洲天堂av综合网| 欧美视频不卡中文| 欧美综合在线观看|