欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#類和結(jié)構(gòu)詳解

 更新時間:2022年04月11日 10:46:39   作者:Ruby_Lu  
本文詳細(xì)講解了C#中的類和結(jié)構(gòu),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

類和結(jié)構(gòu)實(shí)際上都是創(chuàng)建對象(實(shí)例)的模版,每個對象都包含數(shù)據(jù),并提供了處理和訪問數(shù)據(jù)的方法。

類定義了類的每個對象可以包含什么數(shù)據(jù)和功能。

class PhoneCus

    {

        public const string DaySend = "Mon";

        public int CusId;

    }

結(jié)構(gòu)與類的區(qū)別是它們在內(nèi)存中的存儲方式,訪問方式和它們的一些特性(稍后詳細(xì)介紹它們的區(qū)別)。

較小的數(shù)據(jù)類型使用結(jié)構(gòu)可提高性能,在語法上,比較類似,主要區(qū)別是使用關(guān)鍵字struct代替class來聲明結(jié)構(gòu)。

struct PhoneCusStruct
    {
        public const string DaySend = "Mon";
        public int CusId=;
    }

對于類和結(jié)構(gòu),都是用new來聲明實(shí)例:這個關(guān)鍵字創(chuàng)建對象并對其進(jìn)行初始化。

PhoneCus myCus = new PhoneCus();
PhoneCusStruct  myCus2 = new PhoneCusStruct();

上面的例子,類和結(jié)構(gòu)的字段值都默認(rèn)0.

一.類

類中的數(shù)據(jù)和函數(shù)稱為類的成員(數(shù)據(jù)成員和函數(shù)成員)。

1.數(shù)據(jù)成員

數(shù)據(jù)成員是包含類的數(shù)據(jù)————字段,常量和事件的成員。數(shù)據(jù)成員可以是靜態(tài)數(shù)據(jù)。類成員總是實(shí)例成員,除非用static顯示聲明。

2.函數(shù)成員

函數(shù)成員提供了操作類中數(shù)據(jù)的某些功能,包括方法,屬性,構(gòu)造函數(shù),終結(jié)器,運(yùn)算符以及索引。

(1)方法

*C#區(qū)分函數(shù)和方法。C#中函數(shù)包含上述提到的。

*給方法傳遞參數(shù)

參數(shù)可以通過引用或值傳遞給方法。在變量通過引用傳遞給方法時,被調(diào)用的方法得到的就是這個變量,準(zhǔn)確的説就是指向內(nèi)存中變量的指針。所以在方法內(nèi)對變量進(jìn)行的任何改變在方法退出后仍然有效。

而如果變量通過值傳遞給方法,被調(diào)用的方法得到的是變量的一個相同副本,也就是說,在方法退出后,對變量的修改會丟失。

對于復(fù)雜的數(shù)據(jù)類型,按引用傳遞的效率更高,因?yàn)樵诎粗祩鬟f時,必須復(fù)制大量的數(shù)據(jù)。

注意字符串的行為方式有所不同,因?yàn)樽址遣豢勺兊模宰址疅o法采用一般引用類型的行為方式。在方法調(diào)用中,對字符串所做的改變都不會影響原始字符串。

*ref參數(shù)

像上面所説,值類型通過值傳遞變量是默認(rèn)的。但也可以迫使值參數(shù)通過引用傳遞給方法。為此要使用ref關(guān)鍵字。這樣該方法對變量所做的任何改變都會影響原始值。

static void SomeFunction(int[] ints,ref int i)
        {
            ints[0] = 100;
            i = 100;
        }

在調(diào)用該方法的時候,必須添加ref關(guān)鍵字。

SomeFunction(ints, ref i);
*out參數(shù)

C#要求變量在被引用前必須用一個初始值進(jìn)行初始化。但使用out關(guān)鍵字來初始化可以簡化C# 編譯器所堅(jiān)持的輸入?yún)?shù)的初始化。

在方法的輸入?yún)?shù)前加上out前綴時,傳遞給該方法的變量可以不初始化。而且該變量通過引用傳遞,所以在從被調(diào)用的方法中返回時,對應(yīng)方法對該變量進(jìn)行的任何改變都會保留下來。

在調(diào)用該方法時,仍需要使用out關(guān)鍵字:

static void SomeFunction(int[] ints,out int i)
         {
                ints[0] = 100;
                 i = 100;
         }

        SomeFunction(ints, out i);
*命名參數(shù)

參數(shù)一般需要按定義的順序傳遞給方法。命名參數(shù)允許按任意順序傳遞。

string FullName(string firstName,string lastName)
    {
        renturn firstName+" " +lastName; 
    }

調(diào)用方法:

FullName("John","Doe");
      FullName(lastName:"Doe",firstName:"John");
*可選參數(shù)

參數(shù)也可以是可選的。必須為可選參數(shù)提供默認(rèn)值??蛇x參數(shù)還必須是方法定義的最后一個參數(shù)。

void TestMethod(int notOption,int option = 10)
        {
            Console.WriteLine( notOption + option);
        }
*方法的重載

C#支持方法的重載————方法的幾個版本有不同的簽名(方法名相同,但參數(shù)的個數(shù)和/或類型不同)。

class MathTest
          {
             public int Value;
             public int GetSquare()
             {
                    return Value*Value;
             }

             public  int GetSquare(int x)
             {
                return x*x;
             }
          }

重載方法在參數(shù)方面的一些限制:

兩個方法不能僅在返回類型上有區(qū)別;

兩個方法不能僅根據(jù)參數(shù)是聲明為ref還是out來區(qū)分。

在任何語言中,對于方法重載,如果調(diào)用了錯誤的重載方法,就有可能出現(xiàn)運(yùn)行錯誤。(后面討論如何避免這些錯誤)。

(2)屬性(property)

屬性是一個方法或一對方法,在客戶端看來,它是一個字段。

public string  SomeProperty
        {
            get
           {
                return "value";
            }
            set
            {
                //設(shè)置屬性值
            }
        }

get訪問器不帶任何參數(shù),且必須返回屬性聲明的類型。也不應(yīng)為set訪問器指定任何顯示參數(shù),編譯器會

假定它帶一個參數(shù),器類型也許屬性相同,并表示為value.

private int age
        public int  Age
        {
            get
            {
                return age;
            }
            set
            {
                age = valeu;
            }
        }

注意所用的命名約定,采用C#的區(qū)分大小寫模式,使用相同的名稱,但公有屬性采用大寫形式命名,如果存在一個等價的私有字段,則采用小寫形式命名。

一些開發(fā)人員喜歡使用把下劃線作為前綴的字段名,如_age,這會為識別字段提供極大的便利。

*只讀和只寫屬性

在屬性定義中省略set訪問器,就會創(chuàng)建只讀屬性。這樣客戶端代碼只可以讀取該屬性的值,但不能設(shè)置值。

private int age
        public int  Age
        {
            get
            {
                return age;
            }
        }

同樣在屬性定義中省略get訪問器,就會創(chuàng)建只寫屬性。

*屬性的訪問修飾符

C#允許給屬性的gei和set訪問器設(shè)置不同的訪問修飾符,所以屬性可以有公有的get訪問器和受保護(hù)的set訪問器。

在gey和set訪問器中,必須有一個具有屬性的訪問級別(公有)。

*自動實(shí)現(xiàn)的屬性

如果屬性的set和get訪問器中沒有任何邏輯,就可以使用自動實(shí)現(xiàn)的屬性。這種屬性會自動實(shí)現(xiàn)后背成員變量。

public int  Age
        {
            get;
            set;
        }

不需要聲明private int age;,編譯器會自動創(chuàng)建它。

使用自動實(shí)現(xiàn)的屬性,就不能在屬性設(shè)置中驗(yàn)證屬性的有效性。但必須有兩個訪問器,不能把屬性設(shè)置為只讀或只寫。

  public int  Age
  {
    get;//報(bào)錯
  }

  但是,每個訪問器的訪問級別可以不同,
  public int  Age
  {
    get;
    private set;
  }

(3)構(gòu)造函數(shù)

聲明基本構(gòu)造函數(shù)就是聲明一個與包含的類同名的方法,但該方法沒有返回值。

  public class MyClass
  {
    public MyClass()
    {

    }
    //
  }

一般情況下,如果沒有提供任何構(gòu)造函數(shù),編譯器會在后臺創(chuàng)建一個默認(rèn)的構(gòu)造函數(shù)。這是一個基本的構(gòu)造函數(shù),它只能把所有的成員字段初始化為標(biāo)準(zhǔn)的默認(rèn)值。這通常就足夠了,否則需要編寫自己的構(gòu)造函數(shù)。

構(gòu)造函數(shù)的重載與其它方法的規(guī)則相同??梢詾闃?gòu)造函數(shù)提供任意多的的重載,只要它們的簽名有明顯區(qū)別。

public class MyClass
        {
            public MyClass()
            {

            }

            public MyClass(int i )
            {
                / /
            }
            //
        }

如果提供了帶參數(shù)的構(gòu)造函數(shù),編譯器就不會自動提供默認(rèn)的構(gòu)造函數(shù)。只有在沒有定義任何構(gòu)造函數(shù)的時候,編譯器才會自動提供默認(rèn)的構(gòu)造函數(shù)。

public class MyNum
        {
            private int number;
            public MyNum(int number)
            {
                this.number  =number;
            }
        }

一般使用this關(guān)鍵字區(qū)分成員字段和同名的參數(shù)。

如果試圖使用無參數(shù)的構(gòu)造函數(shù)實(shí)例化對象就會報(bào)錯:

MyNum num = new MyNum();//報(bào)錯

可以把構(gòu)造函數(shù)定義為private或protected,這樣不相關(guān)的類就不能訪問它們:

public class MyNum
        {
            private int number;
            private MyNum(int number)
            {
                this.number  =number;
            }
        }

上述例子沒有為MyNum定義為任何公有或受保護(hù)的構(gòu)造函數(shù)。這就使MyNum不能使用new運(yùn)算符在外部代碼中實(shí)例化,但可以在MyNum類中編寫一個公有靜態(tài)屬性或方法,以實(shí)例化該類。

這在下面兩種情況下受有用的:

類僅用作某些靜態(tài)成員或?qū)傩缘娜萜?,因此永遠(yuǎn)不會實(shí)例化它。

希望類僅通過某個靜態(tài)成員函數(shù)來實(shí)例化。

*靜態(tài)構(gòu)造函數(shù)

C#可以給類編寫無參數(shù)的靜態(tài)構(gòu)造函數(shù)。這種構(gòu)造函數(shù)只執(zhí)行一次,而前面的構(gòu)造函數(shù)是實(shí)例構(gòu)造函數(shù),只要創(chuàng)建類的對象,就會

執(zhí)行它。

  class MyClass
  {
    static MyClass()
    {

    }
  }

編寫靜態(tài)構(gòu)造函數(shù)的一個原因是,類有一些靜態(tài)字段或?qū)傩裕枰诘谝淮问褂妙愔?,從外部源中初始化這些靜態(tài)字段和屬性。

.NET運(yùn)行庫不能確保什么時候執(zhí)行靜態(tài)構(gòu)造函數(shù),所以不能把要求在某個特定時刻執(zhí)行的代碼放在靜態(tài)構(gòu)造函數(shù)中。也不能預(yù)計(jì)不同類的靜態(tài)構(gòu)造函數(shù)按照什么順序執(zhí)行。但是可以確保靜態(tài)構(gòu)造函數(shù)最多運(yùn)行一次,就在代碼引用類之前調(diào)用它。

在C#中,通常在第一次調(diào)用類的任何成員之前執(zhí)行靜態(tài)構(gòu)造函數(shù)。

注意,靜態(tài)構(gòu)造函數(shù)沒有訪問修飾符,其它C#代碼從來不調(diào)用它,但在加載類時,總是由.NET運(yùn)行庫調(diào)用它,所以像public,private這樣的訪問修飾符就沒有任何意義。出于同樣原因,靜態(tài)構(gòu)造函數(shù)不能帶任何參數(shù),一個類也只能有一個靜態(tài)構(gòu)造函數(shù)。很顯然,靜態(tài)構(gòu)造只能訪問累的靜態(tài)成員,不能訪問類的實(shí)例成員。

無參數(shù)的實(shí)例構(gòu)造函數(shù)與靜態(tài)構(gòu)造函數(shù)可以在同一個類中同時定義。雖然參數(shù)列表相同,但這并不矛盾,因?yàn)樵诩虞d類的時候執(zhí)行靜態(tài)構(gòu)造函數(shù),在創(chuàng)建實(shí)例時執(zhí)行實(shí)例構(gòu)造函數(shù),所以何時執(zhí)行哪個構(gòu)造函數(shù)不會有沖突。

如果任何靜態(tài)字段有默認(rèn)值,就在調(diào)用靜態(tài)構(gòu)造函數(shù)之前指定它們。

下面演示靜態(tài)構(gòu)造函數(shù)的用法:

class MainEntryPoint
{
     static void Main()
     {

      Console.WriteLine("UserPreference:BackColor is " + UserPreference.BackColor.ToString());
     }
}

class UserPreference
{
     public static readonly Color BackColor;
     static UserPreference()
     {
      BackColor = Color.Red;
     }

    private UserPreference()
    {

    }
}

該靜態(tài)變量在靜態(tài)構(gòu)造函數(shù)中進(jìn)行初始化。

*從構(gòu)造函數(shù)中調(diào)用其它構(gòu)造函數(shù)

有時,在一個類中有幾個構(gòu)造函數(shù),這些構(gòu)造函數(shù)包含一些共同的代碼。

  class Car
  {
    private string des;
    private int nWheels;
    public Car(string des,int nWheels)
    {
      this.des = des;
      this.nWheels = nWheels;
    }

    public Car(string des)
    {
      this.des = des;
        this.nWheels = 4;
      }
  }

這兩個構(gòu)造函數(shù)初始化了相同的字段,顯然最好把所有的代碼放在一個地方。C#有一個特殊的語法,稱為構(gòu)造函數(shù)初始化器,可以實(shí)現(xiàn)這個目的。

  class Car
  {
    private string des;
    private int nWheels;
    public Car(string des,int nWheels)
    {
      this.des = des;
        this.nWheels = nWheels;
      }
    public Car(string des):this(des,4)
    {

      }
  }

這里,this關(guān)鍵字僅調(diào)用參數(shù)最匹配的那個構(gòu)造函數(shù)。構(gòu)造函數(shù)初始化器在構(gòu)造函數(shù)的函數(shù)體之前執(zhí)行。

C#構(gòu)造函數(shù)初始化器可以包含對同一個類的另一個構(gòu)造函數(shù)的調(diào)用,也可以包含對直接基類的構(gòu)造函數(shù)的調(diào)用,使用同樣的語法,但應(yīng)用base關(guān)鍵字代替this.初始化器中不能有多個調(diào)用。

3.只讀字段

常量是一個包含不能修改的值的變量。但常量不必滿足所有的要求。有時需要一些一些變量,其值不應(yīng)改變,但在運(yùn)行之前其值是未知的。C#為這種情形提供了另一種類型的變量:只讀字段(readonly)。

readonly關(guān)鍵字比const靈活得多,允許把一個字段設(shè)置為常量,但可以執(zhí)行一些計(jì)算,以確定它得初始值。

其規(guī)則是可以在構(gòu)造函數(shù)中給只讀字段賦值,但不能在其它地方賦值。只讀字段還可以是一個實(shí)例字段,類的每個實(shí)例可以有不同得值。

與const不同,如果要把只讀字段設(shè)置為靜態(tài),就必須顯示得聲明它。

二.匿名類型

var關(guān)鍵字用于表示隱式類型化得變量。var和new關(guān)鍵字一起使用時,可以創(chuàng)建匿名類型。

匿名類型只是一個繼承自O(shè)bject且沒有名稱的類。

var caption = new {FirstName = "John",LastName="Doe"};

這會生成一個包含F(xiàn)irstName,LastName屬性的對象。

創(chuàng)建另一個對象:

var doctor = new {FirstName = "James",LastName="Mc"};

caption和doctor的類型就相同,可以設(shè)置caption = doctor

如果設(shè)置的值來自于另一個對象,就可以簡化初始化器。

var doctor = new {caption.FirstName,caption.LastName};

這些對象的類型名未知。編譯器為類型“偽造”了一個名稱,但只有編譯器才能使用它。

三.結(jié)構(gòu)(struct)

如果僅需要一個小的數(shù)據(jù)結(jié)構(gòu),此時類提供的功能多余我們需要的功能,由于性能原因,最好使用結(jié)構(gòu)。

結(jié)構(gòu)是值類型,它們存儲在棧中或存儲為內(nèi)聯(lián)(inline)(如果它們是存儲在堆中的另一個對象的一部分),其生存期的限制與簡單的數(shù)據(jù)類型一樣。

  • *結(jié)構(gòu)不支持繼承。
  • *對于結(jié)構(gòu),構(gòu)造函數(shù)的方式與類有一些區(qū)別。編譯器總是提供一個無參數(shù)的默認(rèn)構(gòu)造函數(shù),它是不允許替換的。
  • *使用結(jié)構(gòu)可以指定字段如何在內(nèi)存中布局(后面詳細(xì)介紹)

結(jié)構(gòu)實(shí)際上是把數(shù)據(jù)項(xiàng)組合在一起,有時大多數(shù)字段都聲明為public。嚴(yán)格來說,這與編寫.net代碼的規(guī)則相反(字段應(yīng)總是私有的(除const字段外),并由公有屬性封裝)。但是,對于簡單的結(jié)構(gòu),公有字段是可以接受的編程方式。

四.類和結(jié)構(gòu)的區(qū)別

1.結(jié)構(gòu)是值類型

雖然結(jié)構(gòu)是值類型,但在語法上可以把它當(dāng)作類來處理。

struct PhoneCusStruct
    {
        public const string DaySend = "Mon";
        public int CusId=0;
    }

    PhoneCusStruct phoneCusStruct = new PhoneCusStruct();
    phoneCusStruct.CusId=3;

因?yàn)榻Y(jié)構(gòu)是值類型,所以new運(yùn)算符與類和其它引用類型的工作方式不同。new運(yùn)算符并不分配堆中的內(nèi)存,而只是調(diào)用相應(yīng)的構(gòu)造函數(shù),根據(jù)傳送給它的參數(shù),初始化所有的字段。

對于結(jié)構(gòu)編寫下面的代碼是合法的:

  PhoneCusStruct phoneCusStruct;
  phoneCusStruct.CusId=3;

結(jié)構(gòu)遵循其它數(shù)據(jù)類型都遵循的規(guī)則:在使用前所有的元素都必須進(jìn)行初始化。在結(jié)構(gòu)上調(diào)用new運(yùn)算符,或者給所有的字段分別賦值,結(jié)構(gòu)就完全初始化了。

如果結(jié)構(gòu)定義為類的成員字段,在初始化包含的對象時,該結(jié)構(gòu)會自動初始化為0.

結(jié)構(gòu)是會影響性能的值類型,但根據(jù)使用結(jié)構(gòu)的方式,這種影響可能是正面的,也可能是負(fù)面的。正面的影響是為結(jié)構(gòu)分配內(nèi)存時,速度很快,因?yàn)樗鼈儗?nèi)聯(lián)或保存在棧中。在結(jié)構(gòu)超出了作用域被刪除時,速度也很快,不需要等待垃圾回收。負(fù)面影響是,只要把結(jié)構(gòu)作為參數(shù)來傳遞或者把一個結(jié)構(gòu)賦予另一個結(jié)構(gòu),結(jié)構(gòu)的內(nèi)容就會被復(fù)制,而對于類只復(fù)制引用。這樣就會有性能損失,根據(jù)結(jié)構(gòu)的大小,性能損失也不同。

注意,結(jié)構(gòu)主要用于小的數(shù)據(jù)結(jié)構(gòu)。當(dāng)把結(jié)構(gòu)作為參數(shù)傳遞給方法時,應(yīng)把它作為ref參數(shù)傳遞,以避免性能損失(這樣只傳遞了結(jié)構(gòu)在內(nèi)存中的地址)。

2.結(jié)構(gòu)和繼承

結(jié)構(gòu)不能從一個結(jié)構(gòu)中繼承。唯一的例外是對應(yīng)的結(jié)構(gòu)(和其它類型一樣)最終派生于類System.Object。因此結(jié)構(gòu)也可以訪問Object的方法。

在結(jié)構(gòu)中也可以重寫Object中的方法——如ToString()方法。

結(jié)構(gòu)的繼承鏈?zhǔn)牵好總€結(jié)構(gòu)派生于System.ValueType類,System.ValueType類有派生于System.Object。ValueType并沒有給Object添加任何成員,但提供了一些更適合結(jié)構(gòu)的實(shí)現(xiàn)方法。

注意,不能為結(jié)構(gòu)提供其它基類。

3.結(jié)構(gòu)的構(gòu)造函數(shù)

為結(jié)構(gòu)定義構(gòu)造函數(shù)的方式與類的方式相同,但不允許定義無參數(shù)的構(gòu)造函數(shù)。因?yàn)樵谝恍┖币姷那闆r下,.NET運(yùn)行庫不能調(diào)用用戶提供的自定義無參數(shù)構(gòu)造函數(shù),因此Microsoft干脆采用禁止在C#的結(jié)構(gòu)內(nèi)使用無參數(shù)的構(gòu)造函數(shù)。

默認(rèn)構(gòu)造函數(shù)會隱式的把字段初始化,即使提供了其它帶參數(shù)的構(gòu)造函數(shù),也會先調(diào)用它。提供字段的初始值也不能繞過默認(rèn)構(gòu)造函數(shù)。下面代碼會編譯錯誤:

  struct PhoneCusStruct
  {
    public int CusId =0;
  }

如果PhoneCusStruct聲明為一個類,就不會報(bào)錯了。

另外,可以像類那樣為結(jié)構(gòu)提供Close()或Dispose()方法。

五.弱引用

在應(yīng)用程序代碼內(nèi)實(shí)例化一個類或結(jié)構(gòu)時,只要有代碼引用這個對象,就會形成強(qiáng)引用。這意味著垃圾回收器不會清理這個對象使用的內(nèi)存,一般而言這是好事,因?yàn)榭赡苄枰眠@個對象,但是如果這個對象很大,而且不經(jīng)常訪問。這個時候可以創(chuàng)建對象的弱引用。

弱引用允許創(chuàng)建和使用對象,但在垃圾回收器運(yùn)行時,就會回收對象并釋放內(nèi)存。由于存在潛在的Bug和性能問題,一般不會這么做,但在特定情況下使用是合理的。

弱引用使用WeakReference類創(chuàng)建。因?yàn)閷ο罂赡茉谌我鈺r刻被回收,所以引用該對象前必須確認(rèn)它的存在?! ?/p>

class MainEntryPoint
{
    static void Main()
    {
        // Instantiate a weak reference to MathTest object
        WeakReference mathReference = new WeakReference(new MathTest()); 
        MathTest math;
        if(mathReference.IsAlive)
        {
            math = mathReference.Target as MathTest;
            math.Value = 30;
            Console.WriteLine(
            "Value field of math variable contains " + math.Value);
            Console.WriteLine("Square of 30 is " + math.GetSquare());
        }
        else
        {
            Console.WriteLine("Reference is not available.");
        }
        GC.Collect();
        
        if(mathReference.IsAlive)
        {
            math = mathReference.Target as MathTest;
        }
        else
        {
            Console.WriteLine("Reference is not available.");
        }
    }
}

// Define a class named MathTest on which we will call a method
class MathTest
{
    public int Value;

    public int GetSquare()
    {
        return Value*Value;
    }

    public static int GetSquareOf(int x)
    {
        return x*x;
    }

    public static double GetPi()
    {
        return 3.14159;
    }
}

六.部分類

partial關(guān)鍵字允許把類,結(jié)構(gòu),接口放在多個文件中。

partial關(guān)鍵字的用法:把partial放在class,struct,interface前面即可。

如果聲明類時使用了下面的關(guān)鍵字,這些關(guān)鍵字就必須應(yīng)用于同一個類的所有部分:

public,private,protected,internal,abstract,sealed,new,一般約束

在把部分類編譯后,類的成員和繼承等會合并。

七.靜態(tài)類

如果類只包含靜態(tài)的方法和屬性,該類就是靜態(tài)的。靜態(tài)類在功能上與使用私有靜態(tài)構(gòu)造函數(shù)創(chuàng)建的類相同。都不能創(chuàng)建靜態(tài)類的實(shí)例。

使用static關(guān)鍵字,編譯器可以檢查用戶是否給該類添加了實(shí)例成員。如果是,就會生成一個編譯錯誤。這可以確保不創(chuàng)建靜態(tài)類的實(shí)例。

  static class PhoneCusStruct
  {
    public static void GetPhene()
    {

    }
  }

調(diào)用:PhoneCusStruct.GetPhene();

八.Object類

前面提到,所有的.NET類都派生自System.Object類.實(shí)際上,如果在定義類的時候沒有指定基類,編譯器就會自動假定這個類派生自O(shè)bject類。其實(shí)際意義在于,除了自己定義的方法和屬性等外,還可以訪問Object定義的許多公有的和受保護(hù)的成員方法。這些方法可用于自己定義的其它類中。

System.Object的方法:

  • 1.GetHashCode():如果對象放在名為映射(散列表或字典)的數(shù)據(jù)結(jié)構(gòu)中,就可以使用這個方法。處理這些結(jié)構(gòu)的類使用該方法可以確定把對象放在結(jié)構(gòu)的什么地方。如果希望把類用作字典的一個鍵,就需要重寫這個方法。(后面介紹字典時會詳細(xì)介紹)
  • 2.Equals()和ReferenceEquals()方法:后面會詳細(xì)介紹。
  • 3.Finalize()方法:在引用對象作為垃圾被回收以清理資源時調(diào)用它。Object中實(shí)現(xiàn)的Finalize()方法實(shí)際上什么也沒有做,因而被垃圾回收器忽略。如果對象擁有對未托管資源的引用,則在該對象被刪除時,就需要刪除這些引用,此時一般要重寫Finalize()方法。垃圾收集器不能直接刪除這些未托管資源的引用,因?yàn)樗回?fù)責(zé)托管的資源,于是它只能依賴用戶提供的Finalize()方法。垃圾收集器不能直接刪除這些未托管資源的引用,因?yàn)樗回?fù)責(zé)托管的資源,于是它只能依賴用戶提供的Finalize方法。
  • 4.GetType()方法:這個方法返回從System.Type派生的類的一個實(shí)例。這個對象可以提供對象成員所屬類的很多信息。System.Type還提供了.NET的反射技術(shù)的入口。
  • 5.MemberwiseClose()方法:這個方法復(fù)制對象,并返回對副本的一個引用(對于值類型,就是一個裝箱的引用)。得到的副本是一個淺表復(fù)制,即它復(fù)制了類中的所有值類型。如果類包含內(nèi)嵌的引用,就只復(fù)制引用,而不復(fù)制引用的對象。這個方法是受保護(hù)的,所以不能用于復(fù)制外部的對象(可以復(fù)制父類的對象)。該方法不是虛方法,所以不能重寫。
  • 6.ToString()方法:是獲取對象的字符串表示的一種快捷方式。當(dāng)只需要快速獲取對象的內(nèi)容,以進(jìn)行調(diào)試時,就可以使用這個方法。在數(shù)據(jù)的格式化方面,它幾乎沒有提供選擇,比如:在原則上日期可以表示為許多不同格式,但DateTime.ToString()沒有在這方面提供任何選擇。這個方法是虛方法,可以重寫這個方法以返回這些類型的正確字符串表示。

九.擴(kuò)展方法

如果有類的源碼,繼承就可以給對象添加方法。但如果沒有源代碼,則可以使用擴(kuò)展方法,它允許改變一個類,但不需要該類的源代碼。

擴(kuò)展方法是靜態(tài)方法,它是類的一部分,但實(shí)際上沒有放在類的源代碼中。假定PhoneCusStruct類需要一個Add()方法,但不能修改源代碼,就可以創(chuàng)建一個靜態(tài)類,把Add()方法添加為一個靜態(tài)方法:

  public static class PhoneExtension
  {
    public static void Add(this PhoneCusStruct phoneCusStruct,string phone)
    {
    //
    }
  }

注意擴(kuò)展方法的第一個參數(shù)是要擴(kuò)展的類型,它放在this關(guān)鍵字的后面。這告訴編譯器,這個方法是PhoneCusStruct類型的一部分。在這個例子中,PhoneCusStruct是要擴(kuò)展的類型。在擴(kuò)展方法中,可以訪問所擴(kuò)展類型的所有公有方法和屬性。

調(diào)用:

PhoneCusStruct p =new PhoneCusStruct();
p.Add();//即使方法是靜態(tài)方法,也需要使用實(shí)例方法的語法。

如果擴(kuò)展方法與類中的某個方法同名,就不會調(diào)用擴(kuò)展方法。類中已有的任何實(shí)例方法優(yōu)先。

到此這篇關(guān)于C#類和結(jié)構(gòu)的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論