小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

C#匿名類和擴展方法 - MIDI - 博客園

 woshishenxiande 2011-05-24
一、用var定義變量

    在C#3.0中提供了一種新的聲明變量的方式,這就是var。通過這個關(guān)鍵字,在聲明變量時就無需指定類型了,變量類型是在初始化時由編譯器確定的。代碼如下:

var ss = "abcd";
MessageBox.Show(ss.GetType().ToString());

上 面的代碼將顯示System.String,從而證明C#編譯器已經(jīng)將ss編譯成了String變量了。而在輸出ss后,再輸入“.”后,會看到將 String類型變量的相應(yīng)方法和屬性也列出來了,因此可以斷定,C#將ss看成了String類型,而不是Object。所以使用var定義變量同時可 以擁有Object和強類型的優(yōu)點。
     不過大家不要將var看成是javascript的var,它們的區(qū)別是,javascript是弱類型的語言,而且javascript中的變量(也包括用var聲明的變量)可以變換類型,如下面的javascript所示:

var s = "abcd";
s=3;
alert(s);

    上面的代碼第一次給s賦了一個字符串,而第二行代碼又給賦了一個整數(shù)。這樣的代碼在javascript中沒有任何問題。但在C#3.0中,var變量一但被初始化,確定類型后,就無法改變類型了。如下面的代碼是無法編譯通過的:

var ss = "abcd";
ss = 44;

    綜上所述,在使用var定義變量時有以下四個特點:

1.   必須在定義時初始化。也就是必須是var s = “abcd”形式,而不能是如下形式:
var s;
s = “abcd”;

2.   一但初始化完成,就不能再給變量賦與初始化值類型不同的值了。

3.  var要求是局部變量。

4.  使 用var定義變量和object不同,它在效率上和使用強類型方式定義變量完全一樣。但筆者建議如果事先知道變量的類型,盡量使用強類型方式來聲明變量。 否則,就會造成由于大量使用var,而使得開發(fā)人員很難斷定某個變量是什么類型。這樣不利于程序的維護和升級。

    雖然var有利有弊,但筆者個人認(rèn)為,如果將動態(tài)語言轉(zhuǎn)換成C#語言,可以考慮使用var來定義變量。這是因為動態(tài)語言沒有類型,而要將其轉(zhuǎn)換成強類型的 C#語言,就必須給變量指定個類型,但事先確定類型是很費勁的,不如將其指定成var,再由C#編譯器去確定變量的具體類型。那么如果在轉(zhuǎn)換的過程中,發(fā) 現(xiàn)動態(tài)語言的變量改變了類型,該怎么辦呢?這個可以使用第三部分要講的“匿名類”來解決這個問題。

二、初始化
    如果一個類有public字段,在建立類的對象實例時可以使用下面的代碼來初始化這些字段;

public class MyClass
{
    public String field1;
    public int field2;
    public bool field3;
}

MyClass my = new MyClass();
my.field1 = “abcd”;
my.field2 = 44;
my.field3 = true;

    在C#3.0中提供了一種更簡便的方法來初始化這些public變量,代碼如下:

MyClass my = new MyClass
{
    field1 = “abcd”,
    field2 = 44;
    field3 =true;
};

    上面的代碼的寫法有些象帶參數(shù)的構(gòu)造方法,但這將不是調(diào)用了MyClass的構(gòu)造方法(因為MyClass并沒有帶三個參數(shù)的構(gòu)造方法),而只是C#編譯 器玩的一個魔術(shù)。實際上,上面的代碼在編譯后,仍然和使用傳統(tǒng)的初始化字段的方法一樣。只是在語法上看起來更簡單(至少不用寫那么多個my)。要注意的 的,使用這種方法初始化,必須是public的字段(不能是protected、private或默認(rèn)修飾符的字段)。
    在C#3.0中還改進了對集合類的初始化方式(使其初始化的方式類似于數(shù)組)。但遺憾的是,這種初始化方式只支持用泛型的集合類,也就是說,只有實現(xiàn)了 System.Collections.Generic.違規(guī)廣告ection<T>的集合類才可以使用這種初始化方法。代碼如下:

List<string> myList = new List<string> { "data1", "data2", "data3" };
foreach (string data in myList)
{
    textBox1.AppendText(data);
}

三、匿名類

    在C#3.0中提供了一種新的建立類的方法,代碼如下:
var my = new
{
    field1 = "abcd",
    field2 = 12
};
MessageBox.Show(my.field1);

    C#編譯器會自動推斷my是一個有兩個public字段的類的對象實例。也就是說相當(dāng)于下面的代碼:

public class MyClass
{
    public String field1;
    public int field2;
}

var my = new MyClass();
my.field1 = "abcd";
my.field2 = 25;
MessageBox.Show(my.field1);

    在第一部分講到如果動態(tài)語言在給變量賦值的過程中改變了變量類型,如果將其轉(zhuǎn)換為強類型語言。當(dāng)然,一種方法是將變量聲明成object類型,或是使用匿名類來解決這個問題。代碼如下:
var myVar = new
{
    field_string = “abcd”
    field_int = 12;
};

    然后根據(jù)當(dāng)前這個變量所使用的類型來決定該使用哪個類字段。

四、擴展方法

    這個世界上總是存在著很多奇妙的東西。然而,在這部分所介紹的擴展方法就是其中之一。從字面上看可能讀者很難猜透“擴展方法”是什么意思。然而,看了下面的例子,就會感覺到非常的奇妙。

namespace ExtMethod
{
    public class Class1
    {
        public String s = "bill";
    }
    public class Class2 : Class1
    {
    }
    public static class AnyClassName
    {
        public static String getName(this Class1 class1)
        {
            return class1.s + class1.s;  
        }
    }

    public partial class Form1 : Form
    {
         
        private void button1_Click(object sender, EventArgs e)
        {
            Class1 c = new Class1();
            MessageBox.Show(c.getName());            
            Class2 c = new Class2();
            MessageBox.Show(c.getName());            
        }
    }
}

    看到上面的代碼,也許很多人會感到奇怪,在Class1和Class2中并沒有g(shù)etName方法,怎么在調(diào)用時出來個getName方法呢?實際上,這 就是擴展方法的用法,從本質(zhì)上說,擴展方法就是將靜態(tài)方法(必須聲明成static)插入到某個類和其子類中(也就是說,在這些類中可以使用在外部定義的 靜態(tài)方法)。那么要往哪個類中插入呢?這就要在定義靜態(tài)方法時指定了。大家可以看看getName方法的第一個參數(shù),使用了this關(guān)鍵字,這就表明這個 方法是一個擴展方法,后面的類型就是要插入該方法的類,在本例中是Class1,也就是說在Class1及其子類中都可以使用getName方法。上面的 調(diào)用代碼也相當(dāng)于下面的代碼:
Class2 c = new Class2();
MessageBox.Show(AnyClassName.getName(c));

    但使用c.getName可能會更好一些,而且也降低了對靜態(tài)方法所在的類(AnyClassName)的依賴性。

    在使用擴展方法時應(yīng)注意以下幾點:

1.  擴展方法所在的類名可以是任意合法的類名。

2.  擴展方法所在的類必須和使用擴展方法的代碼在同一個命名空間里,否則無法編譯通過。

3.  在 本例中,Class1和Class2只能聲明成public,因為AnyClassName被聲明為public。如果AnyClassName不加修飾 符,Class1和Class2也可以不加修飾符,當(dāng)然,也可以被聲明為public。也就是說,Class1和Class2必須有比 AnyClassName具有更強的訪問性。如下面代碼所示:
    class Class1
    {
        public String s = "bill";
    }
    class Class2 : Class1
    {
    }
    static class AnyClassName  // 這時如果前面加public是無法編譯通過的。
    {
        public static String getName(this Class1 class1)
        {
            return class1.s + class1.s;  
        }
    }

4.   如果在Class1或Class2中已經(jīng)有g(shù)etName方法了,那么Class1或Class2中的getName優(yōu)先級更高。也就是說,擴展方法是無法覆蓋原類中的同名(參數(shù)名和類型也相同)的方法的。

    擴展方法尤其在很多類需要同樣的方法,而這些類又無法繼承其它類時特別有用。當(dāng)然,在要對某個類進行擴展,但我們并沒有源代碼時,擴展方法也可以派上用場。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多