【译】《Pro ASP.NET MVC4 4th Edition》第四章(一)
本文地址: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。