程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> [C#詳解] (1) 自動屬性、初始化器、擴展方法

[C#詳解] (1) 自動屬性、初始化器、擴展方法

編輯:C#入門知識

[C#詳解] (1) 自動屬性、初始化器、擴展方法


    新的一年,新的開始。來博客園安家已經快兩個月了。每天看博客、寫博客、評論、回答博問已經漸漸養成了一種習慣。可以很明顯的感覺到泡在博客園裡真的可以學到很多,不論是技術文章的還是一些記敘經歷、抒發感想的隨筆,都讓我從各個方面受益良多。不知道大家是否和我一樣,就是感覺博客園有一種特殊的魔力,讓你沒事就想上去看一眼,看上面是不是又有人發了新文章,而且累了的時候在上面看看非技術的東西也能放松自己。   有時會問自己:在博客園上花了這些時間和精力,是否值得?畢竟這也算是"義務勞動",不為自己創造任何價值,通俗點說就是不掙錢。但是每想一次這個問題我都會更加堅定自己的選擇。堅持博客園的理由有三:   不斷地利用博客園中的技術知識提高自己的技術水平,這無疑是在增加自身的價值。我覺得要想拿高工資,最本質的問題就是提高自身價值。對於我們技術人員來講,就是知識面越廣、掌握的技術越深入、編碼的速度越快、質量越高、解決難題的問題越強,我們的價值就越高。博客園在這些方面對我們都是有幫助的。 博客園中的非技術博客和新聞,讓我們可以了解到同行業的人的工作、生活以及感情狀態。並能針對程序員提供對口的業界新聞。這樣可以讓我對自己、以及同行業的人、包括整個行業有了更加清楚的認識。它讓我對自己在行業中所處的地位有一個更加清晰的認識,這樣一來可以更加准確的把握自己,更好的規劃自己的職業生涯。 博客園是一個展示的舞台。我看到很多博客裡有發自己公司的招聘廣告,或者推銷自己的產品、自己的網站。沒錯,他們用這個優質的程序員聚集的平台,為自己打廣告,而且還是免費的。這何樂而不為呢。對於目前的我來說,暫時還不需要廣告什麼,但是通過博客讓更多的人認識我,了解到我的技術水平,肯定有百利而無一害的。免費給自己做廣告,怎麼看都是賺的。 因此,堅持博客園絕對是一個現實的決定。我相信我能一直做下去。   回到我們的博客本身。之前寫了10篇MVC5 + EF6 + Bootstrap3系列教程,今年會繼續寫下去。畢竟這三項技術都是我大大看好的。在寫這個系列的時候,有些遺憾的是,很多C#本身的技術點與MVC關系不大。詳細寫的話怕跑題,不寫怕讀者看不懂,一直都有點尴尬。因此我新開了這個專題[C#詳解]來把那些曾經要講而沒有講的東西一一講講清楚。這樣自己也安心了。因此看了[C#詳解]系列會使你在看MVC5 + EF6 + Bootstrap3系列時更加清楚明白。而看[C#詳解]時也可以去MVC5 + EF6 + Bootstrap3找到這些知識點的實際應用場景。這樣相輔相成,效果應該很好。   屬性與自動屬性 在解釋自動屬性之前有必要先說說屬性。   屬性 我們知道要符合面向對象編程的原則,一個類裡面的變量最好是私有的。如下所示:   class Student {     private int _id; } 這樣保證了類的封裝性。可是把它封裝起來總得有辦法從外部訪問它,要不然就沒有存在的必要了。因此這裡我們就用到了屬性。代碼如下所示:      1 class Student  2 {  3     private int _id;  4     public int Id  5     {  6         get  7         {  8             return _id;  9         } 10         set 11         { 12             _id = value; 13         } 14     } 15 }   上面代碼中第4行定義了一個名為Id的屬性,通過它就能訪問到私有變量_id。Id屬性內部有get和set兩個訪問器,get訪問器用於獲取私有變量的值,set訪問器用於給私有變量賦值。下面的代碼展示如何使用屬性:   1 Student student = new Student(); 2 student.Id = 3; 3 Console.Write(student.Id); 第2行調用set訪問器給Id賦值,第3行,調用get訪問器獲取Id值顯示出來,結果如下:       屬性的功能不僅如此,我們可以給get訪問器加入代碼來對輸出做處理或者給set加入代碼來對賦值做處理。示例如下:      1 class Student  2 {  3     private int _id;  4     public int Id  5     {  6         get  7         {  8             return _id + 100;  9         } 10         set 11         { 12             if (value > 0) 13             { 14                 _id = value; 15             }  16             else 17             { 18                 _id = 0; 19             } 20         } 21     }   第8行的代碼使Id屬性在輸出時加100,第12-19行,使Id屬性在賦值時若值小於0,則賦值為0。   用下面代碼調用上面的類。   1 Student student = new Student(); 2 student.Id = -3; 3 Console.Write(student.Id); 第二行執行後Id屬性會賦值為0,然後在輸出時會變為100。   自動屬性 屬性的定義是繁瑣的,這裡我們就可以用自動屬性來簡化代碼。同樣是定義一個對輸入輸出不做任何特殊處理的屬性,我們可以這樣寫:   1 class Student 2 { 3     public int Id { get; set; } 4 } 第3行就是我們的自動屬性了,其寫法就是在屬性後加{ get; set; }。省了私有變量和訪問器的定義,一行就搞定,但其功能還是和以前的屬性一模一樣。這就是自動屬性的好處。但是自動屬性不能實現前面提到過的對輸入輸出做特殊處理。   另外,想要把一個屬性變為只讀的,用自動屬性可以這樣寫:     1 class Student 2 { 3     public Student(int id) 4     { 5         Id = id; 6     } 7     public int Id { get; private set; } 8 }   上面代碼中第7行在set訪問器前面加上private,屬性賦值沒辦法被外部調用,自然是變成只讀屬性了。但在第3-6行要記得加入構造函數給屬性賦初值。這個類的調用方法如下:   1 Student student = new Student(3); 2 Console.Write(student.Id); 第1行用構造函數給Id賦值,第2行獲取所賦的值。結果如下:       點我看自動屬性   初始化器 初始化器分為對象初始化器和集合初始化器。下面一一介紹。   對象初始化器 對象初始化器的作用,簡單點說就是可以使我們初始化一個類的代碼變得更簡潔。比如下面這個類:   class Person {     public string Name { get; set; }     public int Age { get; set; }     public string Address { get; set; } } 我們要初始化它並對它賦值的話通常要這樣:   Person person = new Person(); person.Name = "Slark"; person.Age = 100; person.Address = "Xi'an"; 這裡我們用了一行創建對象語句,加三行賦值語句。這裡光person這個變量就出現了4遍,繁瑣。用對象初始化器來代替這些操作:   Person person = new Person { Name = "Slark", Age = 100, Address = "Xi'an" }; 同樣的效果,對象初始化器只用了一行,簡潔!可以看到對象初始化器將創建對象和賦值合為一行,其中賦值就是在後面大括號裡做的。這裡的賦值可以給所有屬性賦值,也可以給部分屬性賦值。   集合初始化器 既然要講集合初始化器,那麼我們就先來創建一個集合:   List<int> intList = new List<int>(); intList.Add(1); intList.Add(2); intList.Add(3); 好,這裡我們用4行代碼創建了一個3個元素的集合。集合初始化器的出現大大減少了我們對這種操作的代碼量。其對應的集合初始化器代碼為:   List<int> intList = new List<int> { 1, 2, 3 }; 嗯,真的少寫了很多。集合初始化器的原理也很簡單,就是它默默的為我們調用了List的Add方法依次為我們添加了這3個元素。   這裡我們再給一個綜合運用集合初始化器和對象初始化器的例子:   List<Person> personList = new List<Person> {     new Person { Name = "Slark1", Age = 101, Address = "Xi'an1" },     new Person { Name = "Slark2", Age = 102, Address = "Xi'an2" },     new Person { Name = "Slark3", Age = 103, Address = "Xi'an3" } }; 代碼裡用集合初始化器初始化了personList,然後用對象初始化器初始化了3個Person對象實例。這其中省了多少代碼,真是不談了。   點我看初始化器應用實例   擴展方法 擴展方法,簡單點說就是可以在不改變現有類的情況下給這個類添加方法。我覺得擴展方法的最大意義在於我們可以給那些我們根本無法修改的類,比如String,添加我們自定義的方法。既然無法通過修改來添加,那就只能通過擴展了。   這讓我想到了開閉原則(Open-Close Principle,OCP):一個軟件實體應該對擴展開放,對修改關閉。   既然類對擴展開放了,我們就趕緊來試試吧!   無參數擴展方法 先試著給String添加一個DoubleString方法,就是把這個字符串輸出兩遍。   先創建一個靜態類StringExtension:      1 static class StringExtension  2 {  3     public static string DoubleString(this string str)  4     {  5         return str + str;  6     }  7 }   注意第1行,我們把要擴展的方法放在一個類裡,並且這個類必須是靜態類,要加static。類的名字隨便起,無所謂。第3-6行就是我們想要擴展的方法。這個方法比較特殊,在定義的時候要寫成靜態方法,但是在調用的時候要當實例方法用。這個方法的參數寫成this string str 表示要把這個方法加到String類中。但是這個方法在調用時是不能加參數的。   調用方法如下:   string str = "ABCD"; Console.Write(str.DoubleString()); 可以看到,擴展的方法DoubleString被調用的時候被當作實例方法,並且沒有參數。運行結果如下:       結果符合我們的預期。   帶參數擴展方法 如果要給擴展方法帶參數怎麼辦?示例代碼如下:      1 static class StringExtension  2 {  3     public static string RepeatString(this string str, int row,int column)  4     {  5         string s = string.Empty;  6         for (int i = 0; i < row; i++) {   7             for (int j = 0; j < column; j++)  8         {  9             s += str + " "; 10         } 11             s += "\r\n"; 12         } 13             return s; 14     } 15 }   注意第3行這裡一共有3個參數,其中後兩個參數會在調用這個擴展函數的時候被賦值,這裡這個RepeatString函數會把一個字符串寫成幾行幾列的矩陣。   調用方法如下:   string str = "ABCD"; Console.Write(str.RepeatString(3,4));

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved