博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MVC(4)——学习mvc的基础_C#语言的语言特性
阅读量:2241 次
发布时间:2019-05-09

本文共 9448 字,大约阅读时间需要 31 分钟。

经过前三节的了解,我们大概了解了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;}    
Result
@Model

后面部分将使用一个依赖于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; }        }    }}

以上代码:

二、一次性创建对象并设置其属性——使用对象或集合初始化器

编程任务中构造一个新的对象,然后给属性赋值的任务量也非常的大。如下代码中,它展示了在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
intlist = new List
{ 10, 20, 30, 40 }; Dictionary
mydic = new Dictionary
{ { "apple", 10 }, { "orange", 20 }, { "plum", 30 } }; return View("Result",(object)stringArray[2]); } }}

这里写图片描述

整理的代码:

三、对不能修改的类添加功能——使用扩展方法

  扩展方法(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
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
{ 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便会找到它们。

代码实现:

备注:对接口运用扩展方法原理同上。

四、隐含类型——使用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、敲代码。

你可能感兴趣的文章
seq2seq 的 keras 实现
查看>>
seq2seq 入门
查看>>
什么是 Dropout
查看>>
用 LSTM 做时间序列预测的一个小例子
查看>>
用 LSTM 来做一个分类小问题
查看>>
详解 LSTM
查看>>
按时间轴简述九大卷积神经网络
查看>>
详解循环神经网络(Recurrent Neural Network)
查看>>
为什么要用交叉验证
查看>>
用学习曲线 learning curve 来判别过拟合问题
查看>>
用验证曲线 validation curve 选择超参数
查看>>
用 Grid Search 对 SVM 进行调参
查看>>
用 Pipeline 将训练集参数重复应用到测试集
查看>>
PCA 的数学原理和可视化效果
查看>>
机器学习中常用评估指标汇总
查看>>
什么是 ROC AUC
查看>>
Bagging 简述
查看>>
详解 Stacking 的 python 实现
查看>>
简述极大似然估计
查看>>
用线性判别分析 LDA 降维
查看>>