从简单的数据类型开始
C# 1
public class Product
{
private string name;
public string Name {
get { return name; }
set { name = value; }
}
private decimal price;
public decimal Price
{
get { return price; }
set { price = value; }
}
public Product(string name, decimal price)
{
this.name = name;
this.price = price;
}
public static ArrayList GetSampleProducts()
{
ArrayList list = new ArrayList();
list.Add(new Product("A", 1));
list.Add(new Product("B", 2));
list.Add(new Product("C", 3));
list.Add(new Product("D", 4));
return list;
}
public override string ToString()
{
return string.Format("{0}:{1}", name, price);
}
}
1.没有泛型,ArrayList创建类型时会错误
2.没有private set方法
3.先创建私有字段,在创建对应的属性比较麻烦。类似于Java中的Java Bean
C# 2
public class Product
{
private string name;
public string Name {
get { return name; }
private set { name = value; }
}
private decimal price;
public decimal Price
{
get { return price; }
private set { price = value; }
}
public Product(string name, decimal price)
{
Name = name;
Price = price;
}
public static List<Product> GetSampleProducts()
{
List<Product> list = new List<Product>();
list.Add(new Product("A", 1));
list.Add(new Product("B", 2));
list.Add(new Product("C", 3));
list.Add(new Product("D", 4));
return list;
}
public override string ToString()
{
return string.Format("{0}:{1}", name, price);
}
}
1.引入泛型,增加了代码的安全性
2.使get和set的访问权限分开,可以单独定义get和set的访问属性
C# 3
public class Product
{
public string Name { get; private set; }
public decimal Price { get; private set; }
public Product(string name, decimal price)
{
Name = name;
Price = price;
}
public Product(){}
public static List<Product> GetSampleProducts()
{
return new List<Product>()
{
//调用构造函数(string,decimal),生成一个
new Product("A", 1),
new Product("B", 2),
new Product("C", 3),
new Product("D", 4),
//也是调用构造器(),生成一个。生成后在将里面的值赋值。
new Product{ Name="E",Price=5},
};
}
public override string ToString()
{
return string.Format("{0}:{1}", Name, Price);
}
}
1.没有了字段,全部用属性来表示,增强了一致性
2.可以在调用构造函数时为属性赋值
C# 4
public class Product
{
private readonly string name;
public string Name { get{ return name; } }
private readonly decimal price;
public decimal Price
{
get { return price; }
}
public Product(string name, decimal price)
{
this.name = name;
this.price = price;
}
public Product(){}
public static List<Product> GetSampleProducts()
{
return new List<Product>()
{
//调用构造函数(string,decimal),生成一个
new Product("A", 1),
new Product("B", 2),
new Product("C", 3),
new Product("D", 4),
};
}
public override string ToString()
{
return string.Format("{0}:{1}", name, price);
}
}
1.提供了readonly关键字,该关键字表示出了在构造方法里面可以对它赋值以外,别的地方都是只读的。使代码更易理解。
C# 1 | 只读属性 弱类型集合 |
C# 2 | 私有属性赋值方法 强类型集合 |
C# 3 | 自动实现的属性,增强的集合和对象的初始化 |
C# 4 | 用命名实参更清晰的调用构造函数和方法 |
排序和过滤
排序
C# 1
class ProductNameComparer : IComparer
{
public int Compare(object x, object y)
{
Product first = (Product)x;
Product second = (Product)y;
return first.Name.CompareTo(second.Name);
}
}
1.强制类型转换,不安全。
2.一个类只支持一种方式的排序
3.一个排序写的代码过多
C# 2
class ProductNameComparer : IComparer<Product>
{
public int Compare(Product x, Product y)
{
return x.Name.CompareTo(y.Name);
}
}
List<Product> products = Product.GetSampleProducts();
products.Sort(new ProductNameComparer());
foreach (var item in products)
{
Console.WriteLine(item);
}
简化了很多,但是还是不够简洁。最好能直接比较,而不需要额外的建立一个类
List<Product> products = Product.GetSampleProducts();
products.Sort(
delegate(Product x, Product y)
{
return x.Name.CompareTo(y.Name);
});
foreach (var item in products)
{
Console.WriteLine(item);
}
不需要新建一个类,直接定义一个匿名方法。
C# 3
还可以更加简洁,即使用Lambda表达式
List<Product> products = Product.GetSampleProducts();
products.Sort((x, y) => {
return x.Name.CompareTo(y.Name);
});
foreach (var item in products)
{
Console.WriteLine(item);
}
使用扩展方法
List<Product> products = Product.GetSampleProducts();
foreach (var item in products.OrderBy(a=>a.Name))
{
Console.WriteLine(item);
}
前面的方法都会改变products的真实排序,而使用扩展方法则不会改变原来的排序。
C# 1 | 弱类型的比较功能 不支持委托排序 |
C# 2 | 强类型的比较功能 委托比较 匿名方法 |
C# 3 | Lambda表达式 扩展方法 允许列表保持未排序状态 |
查询
C# 1
List<Product> products = Product.GetSampleProducts();
foreach (var item in products)
{
if (item.Price > 10m)
{
Console.WriteLine(item);
}
}
C# 2
List<Product> products = Product.GetSampleProducts();
List<Product> matches =
products.FindAll(delegate(Product p) { return p.Price > 10m; });
Action<Product> print = Console.WriteLine;
matches.ForEach(print);
可以更加容易测试,每个操作可以单独操作。不像C# 1中三种功能都是耦合的
更精简的版本
List<Product> products = Product.GetSampleProducts();
products.FindAll(delegate(Product p) { return p.Price > 10m; })
.ForEach(Console.WriteLine);
C# 3
List<Product> products = Product.GetSampleProducts();
foreach (var item in products.Where(p=>p.Price > 10))
{
Console.WriteLine(item);
}
C# 1 | 条件和操作都是紧密耦合 两者都是硬编码的 |
C# 2 | 条件和操作分开 匿名方法使委托变的简单 |
C# 3 | Lambda表达式使条件变的更容易阅读 |
处理未知数据
C# 2/3
private readonly decimal? price;
public decimal? Price
{
get { return price; }
}
C# 4
public Product(string name, decimal? price = null)
默认参数
C# 1 | 要么维护一个标志 要么更改引用类型的语意,要么利用一个魔数 |
C# 2/3 | 可空类型避免了采用C# 1的繁琐。语法糖进一步简化 |
C# 4 | 可选参数简化了默认设置 |
LINQ
C# 3
List<Product> products = Product.GetSampleProducts();
var filter = from Product p in products
where p.Price > 10
select p;
foreach (var item in filter)
{
Console.WriteLine(item);
}
LINQ可以查询普通数据类型,可以查询XML文档,也可以查询SQL
COM和动态类型
C# 4
简化了COM互操作
添加了动态语言类型dynamic
轻松编写异步代码
C# 5
async Task await