嘗嘗C#的文法糖(自動屬性/匿名方法/Lamda運算式等)-小心蛀牙!

來源:互聯網
上載者:User

-文法糖,意指那些沒有給電腦語言添加新功能,而只是對人類來說更“sweet”的文法,意在使得編程風格更易讀。C#2.0,3.0發布的新特性,除了泛型不是文法糖,其他所有的新特性幾乎都是文法糖。

-但初學者往往因為不瞭解這些文法糖,從而在閱讀代碼的時候,難以理解其真正的運作方式。最著名的莫過於Lamda運算式,第一次看到它,很多人都會頂個大問號把。。。

-文章前面會伴隨一些讓人看著想吐槽的代碼,請大家自行河蟹。然後我們會介紹一些文法糖來潤色一下,方便初學者們知道這些文法糖的原始意義。

  我們來做一個List<T>類的練習。我會寫一個很蛋疼的例子(盡量不用文法糖,當然這很難避免)。首先我定義了一個學生類

public class Student{    private string num;    public string Num { get { return num; } }    private string name;    public string Name { get { return Name; } }    public Student(string num, string name)    {        this.num = num;        this.name = name;    }    public override string ToString()    {        return num + ":" + name;    }}

  現在練習下List<T>的FindAll()方法,它的聲明如下

public T FindAll(Predicate<T>match)

  FindAll方法把Predicate<T>作為參數,Predicate<T>是一個委託,它引用一個謂詞方法-返回布爾值的方法。如果謂詞返回true,表示有一個匹配。

  所以我寫了一個FindStudent類來定義謂詞。這個方法用要搜尋的學生的學號來初始化,FindPredicate()接收一個student對象,比較student對象的學號與建構函式中設定的學號,返回true or false。

 public class FindStudent  //修正於2010/4/20 感謝 Terry_Huang和 Jack Afa指正    {        private string num name;        public FindStudent(string num Name)        {            this.num = num;
this.name = Name; } public bool FindPredicate(Student student) { return student.Name == name; } }

  最後在一個控制台程式裡搜尋名字叫John的學生。

  class Program    {        static void Main(string[] args)        {            List<Student> Students = new List<Student>();            Students.Add(new Student("001", "John"));            Students.Add(new Student("002", "Marry"));            Students.Add(new Student("003", "John"));            FindStudent finder = new FindStudent("John");            foreach (var student in Students.FindAll(new Predicate<Student>(finder.FindPredicate)))            {                Console.Write(student);            }        }    }

  有沒有人看到這已經扛不住了呢,特別是對FindStudent類和FindAll的冗長的用法?

  下面我們來一點一點的潤色把。

  甜死你1號-自動屬性:只需在定義一個類時指定屬性名稱,C#3.0編譯器將自動實現相應的內部的private變數,並自動產生set訪問器和get訪問器。

  甜死你2號-對象初始值設定項:在自動屬性的前提下,在建立對象時可以對任何可訪問的屬性或欄位賦值,而不需要顯示的調用建構函式。

  基於這兩個特性,我們來修改一下Student類:

public class Student{    public string Num { get; set; }    public string Name { get;set; }    public override string ToString()    {        return Num + ":" + Name;    }}

 

  自動屬性會自動產生私人變數,不需要顯示的聲明,並且可以直接通過物件初始設定式對可訪問的屬性和欄位賦值,建構函式也不是必須的。呃,是不是清爽多了。

  甜死你3號-匿名方法 : 我們之前必須首先聲明方法後才能在委託中使用,C#2.0引入匿名方法,可以delegate{ //dosomething}的形式以一種“內聯”的方式來編寫方法代碼,將代碼直接與委託執行個體相關聯,從而使得委託執行個體化的工作更加直觀和方便。

  有些時候我們需要臨時儲存一些運算的中間結果,我們常常會去聲明一個新的類型,以方便儲存這些中間結果。表面上 看起來這很正常,而細想之後就會發現,這個新類型只服務於這個函數,其它地方都不會再使用它了,就為這一個函數而去定義一個新的類型,確實有些麻煩,比如FindStudent類。

  有了匿名方法,FindStudent類已經沒有存在的意義了(大快人心?),因為自動屬性的關係,我們可以直接存取屬性,並且用匿名方法來代替謂詞。

  插播廣告:

  甜死你4號-集合初始設定式:我們除了可以像初始化數組一樣,初始化對象之外,同樣對於集合也可以不用再重複的Add來增加集合項目了,我們來看新的Main函數:

    static void Main(string[] args)        {            List<Student> Students = new List<Student>()            {             new Student(){ Num="001", Name="John"},//使用物件初始設定式初始化對象,代替建構函式             new Student(){ Num="002", Name="Marry"},             new Student(){ Num="003", Name="John"}            };//使用集合初始設定式初始化集合,不用重複調用Add方法            foreach (var student in Students.FindAll(delegate(Student student) { return student.Name == "John"; }))//使用匿名方法完成FindStudent類的功能            {                Console.WriteLine(student);            }            Console.ReadKey();        }

  是不是看著順眼多了。不過foreach這句還是有點不順眼。腫麼辦,我們只好開大招了。

  甜死你終結者號-Lamda運算式:它是升級版的匿名方法,其作用是簡化匿名方法的寫法。寫法(形參列表)=>{函數體}

  拿delegate(Student student) { return student.Name == "John"; }這個匿名方法為例,我們的參數就只有student一個,形參我們就使用s代替。

  Lamda運算式就是 s=>s.Name=="John"。

  順便我們用一下List<T>的ForEach方法。

  又一條廣告: 

  甜死你路人號-匿名型別: 使用var關鍵字來進行型別宣告,而不需要顯示的宣告類型,具體的類型將由編譯器來推斷。

  最終的Main函數就是:

   static void Main(string[] args)        {            List<Student> Students = new List<Student>()            {             new Student(){ Num="001", Name="John"},//使用物件初始設定式初始化對象,代替建構函式             new Student(){ Num="002", Name="Marry"},             new Student(){ Num="003", Name="John"}            };//使用集合初始設定式初始化集合,不用重複調用Add方法            var John = Students.FindAll(s => s.Name == "John");//使用var聲明匿名型別,其實John是個List<Student>            John.ForEach(j => Console.WriteLine(j));//使用Lamda運算式            Console.ReadKey();        }

  這樣的代碼看著就很舒服了。

  當然文法糖還有很多,如文章開頭所說,C#的新特性大多是文法糖。當然還有一些其他的文法糖,比如三元運算子Test?expression1:expression2就有一個文法糖,寫作

  expression1??expression2   2選1,expression1為null則執行expression2。反之執行expression1。

  歡迎大家補充,這裡就不多做介紹了。

  --------------------------------------------我是分割線------------------------------------------------

  文法糖能夠增加程式的可讀性,但凡事都有兩面性。比如你需要在屬性的get方法中寫一些邏輯,顯然自動屬性就不適用了。所以不必強求。

  咱別硬吃把牙吃壞了。。。

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.