引言

在开始看这本书之前看过一些技术博客,填补自己对于一些知识点的不足。无意中发现了《深入理解C#》这本书,本书主要探讨C# 2、C# 3和C# 4的细节与特性,所以做了一下阅读笔记,欢迎拍砖。

目录

C#1 中定义的产品类型

  public class Product
{
string name;
public string Name
{
get { return name; }
}
decimal price;
public decimal Price
{
get { return price; }
}
public Product(string name, decimal price)
{
this.name = name;
this.price = price;
}
public static ArrayList GetSampleProducts()
{
ArrayList list = new ArrayList();
list.Add(new Product("硬装芙蓉王", 25m));
list.Add(new Product("精白沙", 9m));
list.Add(new Product("软白沙", 5.5m));
return list;
}
public override string ToString()
{
return string.Format("{0}:{1}", name, price);
}
}

缺点:

  1. ArrayList没有提供内部有关编译时的信息。我们很有可能在GetSampleProducts方法中添加一个字符串到ArrayList中,因为ArrayList的Add方法中的参数是object,而编辑器并没有任何反应。
  2. 代码中提供了属性的取值方法,如果添加对应的赋值方法,那么赋值方法也必须是公共的方法。
  3. 创建属性的代码过于复杂。

C#2 中的强类型集合

因C#1中没有泛型,Product类中的静态方法GetSampleProducts,返回的是ArrayList类型,里面添加的元素只能是Product,而在C#2中的改变就是泛型。(新的内容用红色列出)

 public class Product
{
string name;
public string Name
{
get { return name; }
private set { name = value; }
}
decimal price;
public decimal Price
{
get { return price; }
private set { price = value; }
}
public Product(string name, decimal price)
{
Name = name;
20 Price = price;
}
public static List<Product> GetSampleProducts()
{
List<Product> list = new List<Product>();
list.Add(new Product("硬装芙蓉王", 25m));
list.Add(new Product("精白沙", 9m));
list.Add(new Product("软白沙", 5.5m));
return list;
}
public override string ToString()
{
return string.Format("{0}:{1}", name, price);
}
}

优点:

  1. 属性有了私有赋值方法,且可以在构造函数中使用这个赋值方法。
  2. List<Product>告知编辑器里面只能包含Product,试图将一个不同的类型添加到列表中,会造成编译时错误。并且在使用List<Product>时不需要转换结果的数据类型。

针对C#1中的存在的局限性,C#2解决了原先存在的前两个问题。

C#3 中自动实现的属性

相对C#2而言,C#3引入了自动属性和集合初始化器。Product中的属性Name和Price,可以通过自动属性简化代码,而编译器最终生成的代码是一致的。

 public class Product
{
public string Name{ get; private set; }
5 public decimal Price { get; private set; }
Product() { }
public Product(string name, decimal price)
{
Name = name;
Price = price;
}
public static List<Product> GetSampleProducts()
{
return new List<Product>
17 {
18 new Product("硬装芙蓉王", 25m),
19 new Product("精白沙", 9m),
20 new Product("软白沙", 5.5m)
21 };
}
public override string ToString()
{
return string.Format("{0}:{1}", Name, Price);
}
}

优点:

  1. 没有多余的变量与属性相关联,因为类中没有了name和price变量,在类中使用属性名称是相同的。增强了代码的一致性。
  2. 创建的数据列表的方式也截然不同。
  3. 有一个私有的无参构造函数,用于新的基于属性的初始化。

C# 4 中的命名实参

在C#4中引入了命名实参,所谓命名实参是指命名参数调用实参顺序可以和形参不同。

 public class Product
{
readonly string name;
public string Name
{
get { return name; }
}
readonly decimal price;
public decimal Price
{
get { return price; }
}
public Product(string name, decimal price)
{
this.name = name;
this.price = price;
}
public static List<Product> GetSampleProducts()
{
List<Product> list = new List<Product>();
list.Add(new Product(name: "硬装芙蓉王", price: 25m));
24 list.Add(new Product(name: "精白沙", price: 9m));
25 list.Add(new Product(name: "软白沙", price: 5.5m));
return list;
}
public override string ToString()
{
return string.Format("{0}:{1}", name, price);
}
}

按名称对产品进行排序

列表排序最简单的方式就是先将列表排好序,然后遍历并显示其中的项。在上述代码C# 1中,Product类中的静态方法GetSampleProducts,返回的是ArrayList类型,我们要求使用 ArrayList.Sort,要求提供一个IComparer实现。实现代码如下:

  public class ProductNameComparer : IComparer
{
public int Compare(object x, object y)
{
Product i = (Product)x;
Product j = (Product)y;
return i.Name.CompareTo(j.Name);
}
}
  static void Main(string[] args)
{
ArrayList arraylist = Product.GetSampleProducts();
arraylist.Sort(new ProductNameComparer());
foreach(Product pr in arraylist)
{
Console.WriteLine(pr.Name);
}
Console.Read();
}

缺点:

  1. 必须引入额外的类型来帮助排序。
  2. Compare 方法中的强制类型转换。
  3. 假如ArrayList包含一个字符串货其他类型,那么代码会出错——因为在比较时会将字符串强制转型为 Product 。
  4. foreach 循环会隐式将列表中的每个元素转换为 Product 类型,如果其中包含字符串或其他类型,同样会报错。

然后在C#2中引入泛型了可以帮助我们解决上述问题。

 public class ProductNameComparer : IComparer<Product>
{
public int Compare(Product x, Product y)
{
return x.Name.CompareTo(y.Name);
}
}
  static void Main(string[] args)
{
List<Product> arraylist = Product.GetSampleProducts();
arraylist.Sort(new ProductNameComparer());
foreach(Product pr in arraylist)
{
Console.WriteLine(pr.Name);
}
Console.Read();
}

优点:

  1. 开始提供的就是 Product(而不可能是其他类型),在Compare方法中不需要进行强制类型转换。
  2. foreach也不用隐式的类型转换。

如果我们不希望引入额外的类型来帮助排序,而是直接对列表排序。C#2使用委托来排序。代码如下:

 static void Main(string[] args)
{
List<Product> arraylist = Product.GetSampleProducts();
arraylist.Sort(delegate(Product x, Product y)
5 {
6 return x.Name.CompareTo(y.Name);
7 });
foreach (Product pr in arraylist)
{
Console.WriteLine(pr.Name);
}

C#3 可以将匿名方法替换成Lambda表达式的方式进行排序。

 static void Main(string[] args)
{
List<Product> arraylist = Product.GetSampleProducts();
arraylist.Sort((x, y) => x.Name.CompareTo(y.Name));
foreach (Product pr in arraylist)
{
Console.WriteLine(pr.Name);
}
Console.Read();
}

C#3 使用扩展方法进行排序。

 static void Main(string[] args)
{
List<Product> arraylist = Product.GetSampleProducts();
foreach (Product pr in arraylist.OrderBy(p => p.Name))
{
Console.WriteLine(pr.Name);
}
Console.Read();
}

查询集合

查找集合中符合条件的所有元素,是一件很简单的事情,我们来一起来看C#1、C#2、C#之间查询集合的不同。

现要求查找价格大于20的产品信息。

C#1代码:

 static void Main(string[] args)
{
ArrayList arraylist = Product.GetSampleProducts();
foreach (Product pr in arraylist)
{
if (pr.Price > )
{
Console.WriteLine(pr);
}
}
Console.Read();
}

C#2代码:

 static void Main(string[] args)
{
List<Product> list = Product.GetSampleProducts();
Predicate<Product> test = delegate(Product p) //设定查询条件
{
return p.Price > ;
};
List<Product> all = list.FindAll(test); //查询所有价格大于20的产品,并保存到all中
Action<Product> pro = Console.WriteLine; //输出产品信息
all.ForEach(pro); //循环输出产品信息
Console.Read();
}

C#2另外一个版本代码:

 static void Main(string[] args)
{
List<Product> list = Product.GetSampleProducts();
list.FindAll(delegate(Product p) //设定查询条件
5 {
6 return p.Price > 20;
7 }).ForEach(Console.WriteLine);
Console.Read();
}

C#3代码:

 static void Main(string[] args)
{
List<Product> list = Product.GetSampleProducts();
list.FindAll(p => { return p.Price > 20; }).ForEach(Console.WriteLine);
Console.Read();
}
 static void Main(string[] args)
{
List<Product> list = Product.GetSampleProducts();
foreach (Product pro in list.Where(p => p.Price > 20))
{
Console.WriteLine(pro);
}
Console.Read();
}

这篇就写到这里。下篇我们将继续学习《深入理解C#》的相关知识。

学习《深入理解C#》—— 数据类型、排序和过滤 (第一章1.1---1.2)的更多相关文章

  1. 01.C#数据类型、排序、过滤(一章1.1-1.2)

    随着看的文章及探讨越多,越发现自己实在太不定性了,看下<C#深入理解>吧,做一下读书笔记,从中发现自己的不足.闲话不说,进入正题吧. 在C#1中定下一个简单的数据类型 public cla ...

  2. 《深入理解bootstrap》读书笔记:第一章 入门准备

    一.bootstrap框架简介 Bootstrap是最流行的前端开发框架. 什么是框架:开发过程的半成品. bootstrap具有以下重要特性: (1)完整的CSS样式插件 (2)丰富的预定义样式表 ...

  3. python基础知识的学习和理解

    参考链接:https://github.com/yanhualei/about_python/tree/master/python_learning/python_base   python基础知识笔 ...

  4. Java基础系列1:深入理解Java数据类型

    Java基础系列1:深入理解Java数据类型 当初学习计算机的时候,教科书中对程序的定义是:程序=数据结构+算法,Java基础系列第一篇就聊聊Java中的数据类型. 本篇聊Java数据类型主要包括四个 ...

  5. Contoso 大学 - 3 - 排序、过滤及分页

    原文 Contoso 大学 - 3 - 排序.过滤及分页 目录 Contoso 大学 - 使用 EF Code First 创建 MVC 应用 原文地址:http://www.asp.net/mvc/ ...

  6. Compass 更智能的搜索引擎(3)--高亮,排序,过滤以及各种搜索

    要想使得一个搜索系统更加的完美,查询精确度和页面显示算是其中比较重要的两个方面.今天,我们就来谈谈怎么使得我们的搜索系统更加的完美. 关于分词 下载地址 配置 关于高亮 关于排序 原理 冗余字段 使用 ...

  7. 在Object-C中学习数据结构与算法之排序算法

    笔者在学习数据结构与算法时,尝试着将排序算法以动画的形式呈现出来更加方便理解记忆,本文配合Demo 在Object-C中学习数据结构与算法之排序算法阅读更佳. 目录 选择排序 冒泡排序 插入排序 快速 ...

  8. Typescript 学习笔记二:数据类型

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  9. 理解BSTR数据类型 神奇的BSTR

    理解BSTR数据类型 神奇的BSTR - 深蓝的日志 - 网易博客 http://blog.163.com/pugood@126/blog/static/13441759320091111115264 ...

随机推荐

  1. window.onunload | window.onbeforeunload

    先引述一段jQuery 官方对于onunload的评述: The unload event is sent to the window element when the user navigates ...

  2. mosquitto ---配置SSL/TLS

    在服务器电脑上面创建myCA文件夹, 如在/home/qa/ 文件夹下使用命令, mkdir myCA 然后执行以下命令,我们将创建并使用其他用户没有权限访问的目录. sudo chmod 700cd ...

  3. Android异步任务处理框架AsyncTask源代码分析

    [转载请注明出处:http://blog.csdn.net/feiduclear_up CSDN 废墟的树] 引言 在平时项目开发中难免会遇到异步耗时的任务(比方最常见的网络请求).遇到这样的问题.我 ...

  4. js--在页面元素上(移动到或获取焦点)、鼠标离开(或失去焦点)

    1.onfocus() 和 onblur() 是一对相反的事件 但是他们只支持一部分标签 W3C关于onblur的描述:http://www.w3school.com.cn/jsref/event_o ...

  5. Apach 配置虚拟机时候DocumentRoot参数最后不要加斜杠

    DocumentRoot "D:\baiduyun\webroot\jedi\app\static" 这样是可以的 DocumentRoot "D:\baiduyun\w ...

  6. python 中写hive 脚本

    1.直接执行.sql脚本 import numpy as np import pandas as pd import lightgbm as lgb from pandas import DataFr ...

  7. unity, AnimatorCullingMode的一个bug

    我在一个fbx节点上添加了一个Animator,CullingMode设置为Cull Update Transforms(即如果没有激活的SkinnedRenderer就不更新骨骼动画),然后我将这个 ...

  8. python登陆Tom邮箱的代码一例

    本文出处参考:http://www.cnblogs.com/LinuxHunter/archive/2010/11/30/1891635.html 在很多的python 教程中都会讲到登录邮箱或发送邮 ...

  9. Unity3D安卓交互 - 使代码运行在UI线程

    runOnUiThread(new Runnable() { public void run() { // TODO Auto-generated method stub } });

  10. Objective-C函数重载规则

    是按照函数标签是否重复来判断是否为一个重载函数的.