本文地址:http://www.cnblogs.com/outtamyhead/archive/2013/05/03/3056544.html,轉載需保留本地址。
說在前面:
1、由於是頭次翻譯整本書籍,所以錯誤難免,希望大家都提出來,翻譯的不好還望大家少拍磚多鼓勵。
2、該系列沒有按照原文直譯,而是加入了我的一些言語在里面(在沒有改變原意的情況下),所以大家在看的時候希望有所對照。
3、該系列每周出一或二篇博客,因為我最近很忙,一直在加班,很累的說。
4、該系列不提供原版文字,希望看原版的可以自行下載Pdf。
5、該系列省去了前面的廢話,單刀直入,講主體內容。
基本語言特性
C#是一個功能豐富的語言,而我們這本書里使用的並不是所有程序員都熟悉的特性。在這一章中,我們打算看看一個優秀MVC程序員需要知道的C#語言特性。
我們在每一章只有一個簡短的總結。如果你需要更多C#或LINQ的知識,Adam的三本書你可能會感興趣。對於完整的C#指南可以參閱《Introducing Visual C#》,要了解更多的LINQ知識,可以參閱《Pro LINQ in C#》,要了解異步編程,可以參閱《Pro .Net Parallel Programming in C#》。這三本書都由Apress出版。
創建示例工程
在這一部分為了驗證語言的特性,我們已經創建了一個MVC 4工程,叫做LanguageFeatures,並且使用的是Empty模板。這些特性並不是MVC特有的,但是Visual Studio Express 2012 for Web版不支持創建控制台應用程序,所以你不得不創建一個MVC程序如果你想實現這個例子。
我們需要一個簡單的控制器來驗證這些語言特性,所以我們在Controller文件夾中創建了HomeController.cs文件,用到的技術我們已經在第2章說過了。你可以在清單4-1中看到Home控制器的初始內容。
1 using LanguageFeatures.Models; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Web; 6 using System.Web.Mvc; 7 namespace LanguageFeatures.Controllers { 8 public class HomeController : Controller { 9 public string Index() { 10 return "Navigate to a URL to show an example"; 11 } 12 } 13 }
我們要為每一個示例都創建動作方法,所以為了保持工程簡單,Index動作方法的結果是一條信息。為了顯示從我們動作方法返回的結果,我們在Views/Home文件夾下添加了一個叫做Result.cshtml的視圖。你可以在清單4-2中看到視圖中的內容。
@model String @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Result</title> </head> <body> <div> @Model </div> </body> </html>
你可以看到這是一個強類型視圖,模型類型是String--這不是一個復雜的示例並且我們可以容易的把結果作為簡單的字符串進行描述。
使用自動實現的屬性
C#屬性特性可以讓你暴露一個類的一塊數據,這些數據與如何設置和接收數據使用一個松耦合的方式。在清單4-3中,類Product包含一個簡單的例子,這個類我們添加在了Models文件夾中。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 namespace LanguageFeatures.Models { 6 public class Product { 7 private string name; 8 public string Name { 9 get { return name; } 10 set { name = value; } 11 } 12 } 13 }
叫做Name的屬性用粗體標識了。get塊中的語句會在屬性的值被讀取時執行,set塊中的語句在值被分配到屬性時執行(value這個特殊變量負責描述這個被分配的值)。屬性通過其他類來使用,就好比它是一個字段。清單4-4展示了這些內容,代碼在AutoProperty動作方法中。
1 using LanguageFeatures.Models; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Web; 6 using System.Web.Mvc; 7 namespace LanguageFeatures.Controllers { 8 public class HomeController : Controller { 9 public string Index() { 10 return "Navigate to a URL to show an example"; 11 } 12 public ViewResult AutoProperty() { 13 // create a new Product object 14 Product myProduct = new Product(); 15 // set the property value 16 myProduct.Name = "Kayak"; 17 // get the property 18 string productName = myProduct.Name; 19 // generate the view 20 return View("Result", 21 (object)String.Format("Product name: {0}", productName)); 22 } 23 } 24 }
你可以看到屬性值就像一個規則字段一樣被讀取和賦值。使用屬性勝過使用字段,因為你可以在get和set塊中修改語句而不需要修改基於這個屬性的所有類。
提示:你可能注意到在清單4-4中我們在View方法中使用了第二個參數而且是object類型。這是因為View方法有一種重載方法接受兩個String參數還有一種是接受一個String類型參數和一個object參數。為了避免調用錯誤,我們顯示的使用的第二種。我們將在第18章中列出所有View方法的重載方法。
你可以通過啟動工程來看到示例的結果,導航到/Home/AutoProperty(調用目標是AutoProperty動作方法並且會在這一章中將測試每一個例子)。因為我們僅僅從動作方法中傳遞了一個string到視圖上,我們打算以文本的形式向你展現這個結果,而不是截圖。下面是清單4-4調用目標動作方法的結果。
一切都很好,但是當你有一個有很多屬性的類時就變的有點乏味了,所有的屬性都在填充字段。對於一些不必要的冗長,我們需要阻止。在清單4-5中,顯示了在Product.cs文件中的這些屬性。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 namespace LanguageFeatures.Models { 6 public class Product { 7 private int productID; 8 private string name; 9 private string description; 10 private decimal price; 11 private string category; 12 public int ProductID { 13 get { return productID; } 14 set { productID = value; } 15 } 16 public string Name { 17 get { return name; } 18 set { name = value; } 19 } 20 public string Description { 21 get { return description; } 22 set { description = value; } 23 } 24 //...and so on... 25 } 26 }
我們想要屬性具有靈活性,但是我們不需要自定義getter和setter。這個解決方法就是使用自動實現屬性,也被叫做自動屬性。一個自動屬性,你可以生成一個字段支持的屬性模式,不需要在getter和setter中定義字段或者特定的代碼,如清單4-6所示。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 namespace LanguageFeatures.Models { 6 public class Product { 7 public int ProductID { get; set; } 8 public string Name { get; set; } 9 public string Description { get; set; } 10 public decimal Price { get; set; } 11 public string Category { set; get; } 12 } 13 }
當使用自動屬性時有兩點需要注意。第一是我們不定義getter體和setter體。第二是我們不定義該屬性返回的字段。這兩點都會在我們生成類的時候由C#編譯器來替我們做;清單4-4中動作方法里的代碼在不需要修改的情況下就可以工作。
通過使用自動屬性,我們減少了打字,創建的代碼更易讀,並保留着屬性所有的靈活性。入股偶有一天我們需要更改屬性實現的方式,我們可以重新使用規則屬性格式。假設我們需要改變Name屬性的實現方式,如清單4-7所示。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 namespace LanguageFeatures.Models { 6 public class Product { 7 private string name; 8 public int ProductID { get; set; } 9 public string Name { 10 get { 11 return ProductID + name; 12 } 13 set { 14 name = value; 15 } 16 } 17 public string Description { get; set; } 18 public decimal Price { get; set; } 19 public string Category { set; get; } 20 } 21 }
注:注意我們在使用規則屬性時必須都實現getter和setter。C#不支持在單個屬性中混合自動和規則模式的getter和setter。