经过前三节的了解,我们大概了解了mvc。当时在深入了解前,我们想我们应该先了解C#语言的特性,因为它能帮助我们在后期进步的更快。今天大概分析一下如下四个特性。
准备阶段——开启一个项目
在vs中用”ASP.NET Web Application”模板创建了一个新的VisualStudio项目,名称为LanguageFeatureso,选择”Empty(空模板)”作为初始内容,并对在“添加文件夹和核心引用”中选中了“MVC”选项。项目建好后,我们在“Controllers”文件夹中创建Homecontroller.cs。Homecontroller.cs中内容如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using LanguageFeatureso.Models;//此时不要运行程序,因为我们还没有为models创建类文件,当创建类文件的时候,引用的这个命名空间才会有效。
namespace LanguageFeatureso.Controllers
{
public class HomeController : Controller
{
// GET: Home
public string Index()
{
return "下面是一些小Demo!!";
}
}
}
为了显示动作方法的结果,右击Index动作方法,选择”AddView(添加视图)”,并创建一个名称为Result的新视图。该视图文件的内容如下:
@model string @*这个视图模型是强类型的,为string类型,同时,注意这里的model必须小写,否则在第一个实例中,会出现两行结果。*@
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Result</title>
</head>
<body>
<div>
@Model
</div>
</body>
</html>
后面部分将使用一个依赖于System.Net.Http程序集,该程序集默认情况下不会添加到MVC项目中。在VisualStudio的”Project(项目)”菜单中选择”AddReference(添加引用)”,可以打开”ReferenceManager(引用管理器)”窗口。在窗口左侧选择”Assemblies(程序集)”,并勾选”System.Net.Http”选项。
一、简化C#属性——使用自动实现的属性
常规的C#属性可以暴露类的数据片段,这种数据片段与设置和接收数据采取了一种松耦合的方式。下面的代码一个类的简单示例,其名称为“Product”,它位于LanguageFeatures项目的Models文件夹中,类文件名称为product.cs。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace LanguageFeatureso.Models
{
public class Product
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
}
}
名称为”Name”的属性,其get代码块中的语句在读取该属性值时执行,而set代码块中的语句则在对该属性赋值时执行(特殊变量value表示要赋的值)。属性是由其他类来使用的,就好像它是一个字段一样,如下面的代码中。该代码段显示了添加到Home控制器中的Autoproperty动作方法。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using LanguageFeatureso.Models;
namespace LanguageFeatureso.Controllers
{
public class HomeController : Controller
{
// GET: Home
public string Index()
{
return "下面是一些小Demo!!";
}
public ViewResult AutoProperty()
{
//创建一个新的Product对象
Product myProduct = new Product();
// 设置属性
myProduct.Name = "NerlCheng";
//读取属性
string productName = myProduct.Name;
return View("Result",(object)string.Format("Product name:{0}",productName));
}
}
}
可以看出,属性值的读取和设置就像对一个常规字段进行操作一样。使用属性要比使用字段更好,因为你可以修改get块和set块中的语句,而不需要修改依赖于这个属性的类。
通过启动项目并导航到/Home/Autoproperty(该网址的目标是AutoProperty动作方法,这也是对本章的每一个示例进行测试的方式),便可以看到本示例的结果。
属性固然好,但是当一个类有很多属性时,事情就变得有点乏味了一一所有属性都要对字段协调访问,产生了一个不必要的冗长的类文件。如下面的代码示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace LanguageFeatureso.Models
{
public class Product
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
private string _sex;
public string Sex {
get { return _sex; }
set { _sex = value; }
}
}
}
属性要具有灵活性,没有重复的get和set.解决办法是使用一种自动实现的属性,也称为“AutomaticProperty(自动属性)”。利用自动属性,可以采用字段支持式属性模式,而不需要定义这个字段或在get和set中指定代码,如下代码所示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace LanguageFeatureso.Models
{
public class Product
{
public string Name { get; set; }
public string Description { get; set; }
public string Price { get; set; }
public string Category { get; set; }
}
}
注意,这里并未定义get和setr的体,也未定义该属性返回的字段。这两者都由C#编译器在这个类被编译时自动完成。使用自动属性与使用规则属性没什么不同,HomeControllor中的动作方法代码仍会正常工作而无需任何修改。
通过使用自动属性可以减少一些输入,形成更易于阅读的代码,但仍然保持了属性的灵活性。如果需要改变一个属性的实现方式,还可以返回到规则属性的格式。作为演示,下面的代码显示了修改属性构成方式的做法。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace LanguageFeatureso.Models
{
public class Product
{
private string _productid;
private string _name;
public string Name { get; set; }
public string Description { get; set; }
public string Price { get; set; }
public string Category { get; set; }
public string ProductID
{
get { return _productid + Name; }
set { _productid = value; }
}
}
}
以上代码:https://download.csdn.net/download/aiming66/10568921
二、一次性创建对象并设置其属性——使用对象或集合初始化器
编程任务中构造一个新的对象,然后给属性赋值的任务量也非常的大。如下代码中,它展示了在Home控制器中所添加的Createproduct动作方法内容。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using LanguageFeatureso.Models;
namespace LanguageFeatureso.Controllers
{
public class HomeController : Controller
{
// GET: Home
public string Index()
{
return "下面是一些小Demo!!";
}
public ViewResult CreatProduct()
{
//创建一个新对象
Product Myproduct = new Product();
//赋值
Myproduct.ProductID = "100";
Myproduct.Name = "NerlCheng";
Myproduct.Description = "the descripton of NerlCheng";
Myproduct.Price = "20元";
Myproduct.Category = "sprot";
return View("Result",(object)string.Format("Category:{0}",Myproduct.Category));
}
}
}
本示例中,须通过3个步骤来创建Product对象并产生结果:创建对象、设置参数值,然后调用View方法,以便能够通过视图显示其结果。
幸运的是,可以使用对象初始化器(ObjectInitializer)特性一一它能够在一个步骤中创建并填写Product实例。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using LanguageFeatureso.Models;
namespace LanguageFeatureso.Controllers
{
public class HomeController : Controller
{
// GET: Home
public string Index()
{
return "下面是一些小Demo!!";
}
public ViewResult CreatProduct()
{
Product myProduct = new Product {ProductID = "100",Name ="NerlCheng",Description = "the descripton of NerlCheng" ,Price = "20元",Category = "sprot"};
return View("Result",(object)string.Format("Category:{0}",myProduct.Category));
}
}
}
Product 名 称 之 后 所 调 用 的 花 括 号 ( { } ) 形 成 了 初 始 化 器 , 目 的 是 为 参 数 提 供 值 , 以 此 作 为 该 对 象 的 构 造 过 程 。 以 这 种 同 样 的 特 性 作 为 构 造 过 程 , 也 能 对 集 合 和 数 组 的 内 容 进 行 初 始 化。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using LanguageFeatureso.Models;
namespace LanguageFeatureso.Controllers
{
public class HomeController : Controller
{
// GET: Home
public string Index()
{
return "下面是一些小Demo!!";
}
public ViewResult CreateCollecton()
{
string[] stringArray = { "apple","orange","plum"};
List<int> intlist = new List<int> { 10, 20, 30, 40 };
Dictionary<string, int> mydic = new Dictionary<string, int> { { "apple", 10 }, { "orange", 20 }, { "plum", 30 } };
return View("Result",(object)stringArray[2]);
}
}
}
整理的代码:https://download.csdn.net/download/aiming66/10569484
三、对不能修改的类添加功能——使用扩展方法
扩展方法(ExtensionMethod)是指给那些不是咱们拥有的、不能直接修改的类添加方法的一种方便的办法。下面代码中演示了添加到Models文件夹中的ShoppingCart.cs文件,它表示了一个Products对象集合。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace LanguageFeatureso.Models
{
public class ShoppingCart
{
public List<Product> Products { get; set; }
}
}
这是一个很简单的类,其作用是封装一个Product对象的列表。假设,咱们需要能够计算这个ShoppingCart类中Product对象的总值,但不能对ShoppingCart类进行修改,此时我们可以用一个扩展方法来获得所需要的功能。为此我们在Models文件夹的添加MyExtensionMethods.cs文件。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace LanguageFeatureso.Models
{
public static class MyExtensionMethods//扩展方法必须在非泛型静态类中
{
public static decimal TotalPrices(this ShoppingCart cartParam)
{
decimal total = 0;
foreach (Product item in cartParam.Products)
{
total += Convert.ToInt32( item.Price);
}
return total;
}
}
}
在上面的代码中,第一个参数前的this关键字把TotalPrices标记为是一个扩展方法。并且,第一个参数告诉.net 程序这个扩展方法运用了哪个类一一此例为ShoppingCart类。可以通过使用cartParam参数来引用ShoppingCart类的实例,ShoppingCart类是这个扩展方法所运用的类。该扩展方法枚举了ShoppingCart中的所有Product,并返回Product.Price属性的总和。
下面一起来了解一下如何在home 控制器新建的一个名为UseExtension的新动作方法中运用扩展方法。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using LanguageFeatureso.Models;
namespace LanguageFeatureso.Controllers
{
public class HomeController : Controller
{
// GET: Home
public string Index()
{
return "下面是一些小Demo!!";
}
public ViewResult UseExtension()
{
//创建并填充shoppingCart类
ShoppingCart cart = new ShoppingCart
{
Products = new List<Product>
{
new Product { Name="apple",Price="20" },
new Product { Name="puml",Price ="40"}
}
};
//求总价格
decimal total = cart.TotalPrices();
//显示
return View("Result", (object)string.Format("Totalprice:{0}",total));
}
}
}
相信,这里最难理解的就是这一句了
//求总价格
decimal total = cart.TotalPrices();
这里在ShoppingCart对象上调用了TotalPrices方法,就好像它是ShoppingCart类的一部分,尽管它是由一个完全不同的类所定义的扩展方法。如果你的扩展类位于当前类的范围内(意即,它们在同一命名空间中,或是在using语句子项的命名空间之中),.NET便会找到它们。
代码实现:https://download.csdn.net/download/aiming66/10569537
备注:对接口运用扩展方法原理同上。
四、隐含类型——使用var关键字
C#的var关键字允许定义一个局部变量,而不必明确地指定该变量的类型,这称为“类型推断(TypeInference)”或“隐式类型(ImplicitTyping)”。
var myproduct = new Product { Name = "apple", Price = "20" };
string name = myproduct.Name;//编译成功
int count = myproduct.Count;//编译错误
并不是myvariable没有类型,只是要求编译器通过代码来推断它。通过随后的语句可以看到,编译器将只允许调用这个推断类Product的成员(因为Count不属于推断类型的属性,故会出现编译时错误)。
总结:
1、个人认为总结的不是非常的全面,毕竟C#可不是两天就能说明白的。
2、敲代码。