19
好啦,Bob前面讲过的,“我们以后会讲的”的集合,终于出来了!首先,复习一下数组的知识,要定义一个数组,我们可以这么做:
int[] dora = new int[5];
也可以这样做:
int[] dora = {1,2,4,5,0};
可以清楚的看见,数组是要定义类型和长度的,超出了就不行。
这节课首先要介绍的是ArrayList。为了方便起见,我们创建两个类:
class car
{
public car(){}
public car(string mmodel,string ccolor,string vvin)
{
model = mmodel;
color = ccolor;
vin = vvin;
}
public string vin { get; set; }
public string model { get; set; }
public string color { get; set; }
}
class book
{
public book(string aauthor,string ttitle,string iisbn)
{
author = aauthor;
title = ttitle;
ISBN = iisbn;
}
public string author { get; set; }
public string title { get; set; }
public string ISBN { get; set; }
}
▲我用了两个构造函数,觉得自己很强,结果Bob最后说了,不需要构造函数……
加入如下代码:
car car1 = new car("1949","red","001");
car car2 = new car("1937","blue","002");
book book1 = new book("changkaishen","diary","1924-1945sb");
ArrayList myarraylist = new ArrayList();
myarraylist.Add(car1);
myarraylist.Add(car2);
//myarraylist.Add(book1);
foreach (car item in myarraylist)
{
Console.Write(item.color + " ");
}
由于ArrayList是不限类型、不限长度的,所以把注释去掉也没什么关系。但是,当运行到Foreach的时候,就报错了。类型不匹配啊。
Bob说了,当LINQ的第一版刚刚推出的时候,这个ArrayList看着方便,其实不好——容易出错。
所以,在后来的版本中,主要运用的是List与Dictionary。
List的定义是这样的:
List<car> carlist = new List<car>();
(其实我觉得,List更像下界灵活的数组。)
然后,我们能这么用:
carlist.Add(car1);
carlist.Add(car2);
foreach (car item in carlist)
{
Console.WriteLine(item.model);
}
测试是通过的。
再来看一下Dictionary。顾名思义,我们查字典的时候,往往都是找词语的意思的。但是总要有一个索引吧?所以,我们都是找到词语后,再找意思的。
Dictionary也是如此:每个键都有对应的值。
Dictionary<string, car> mydic = new Dictionary<string, car>();
mydic.Add(car1.vin,car1);
mydic.Add(car2.vin,car2);
Console.WriteLine(mydic["001"].model);
▲这里我添加了一个VIN值(其实是Bob加的),结果构造函数都要重构了……
接下来是打破构造函数神话时间:
Bob说了:大家都知道,我们定义数组的时候可以这么做:
string[] dora = { "1", "2", "4", "5", "0" };
以此类推:
car car1 = new car() {model="SB",color="blue",vin ="1924" };
所以,List也可以这么用:
List<car> mylist = new List<car>
{
new car { model = "SB", color = "blue", vin = "1924" },
new car {model = "GOD", color = "RED", vin = "1949" }
};
▲注意!中间的逗号别忘了!
当时,用了构造函数的我内心相当沮丧……
20
这节课记忆的内容很多,理解的比较少,我就以代码注释的形式说一下。
using System;
using System.Collections.Generic;//Ctrl + . 自动生成
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace UnderstandingLINQ
{
class Program
{
static void Main(string[] args)
{
List<Car> myCars = new List<Car>() {//上节课讲的
new Car() { VIN="A1", Make = "BMW", Model= "550i", StickerPrice=55000, Year=2009},
new Car() { VIN="B2", Make="Toyota", Model="4Runner", StickerPrice=35000, Year=2010},
new Car() { VIN="C3", Make="BMW", Model = "745li", StickerPrice=75000, Year=2008},
new Car() { VIN="D4", Make="Ford", Model="Escape", StickerPrice=25000, Year=2008},
new Car() { VIN="E5", Make="BMW", Model="55i", StickerPrice=57000, Year=2010}
};
//LINQ类SQL
/* var bmws = from car in myCars
where car.Make == "BMW"
&& car.Year == 2000
select car;//这是第一种方式,类似SQL语句的、对于List的查询。
*/
//LINQ排序
/* var paixv = from car in myCars
orderby car.Year descending
select car;*/
//同样的,这是用SQL降序排序//这两个地方的car我不大清楚,应该是临时变量。
//LINQ方法
//var bmws = myCars.Where(p => p.Make == "BMW" && p.Year == 2010);
//这是用Lambda语言写出来的,这里的p可以替换为任意字母。//var 和 VB 的完全不同,这里的var是用来表示不确定类型的变量的,意思是让编译器自己决定。
//var paixv = myCars.OrderByDescending(p => p.Year);
//降序排序,默认升序
//var diyi = myCars.OrderByDescending(p => p.Year).First(p => p.Make == "BMW");//方法组合嵌套
// Console.WriteLine(myCars.TrueForAll(p => p.Year < 2012));//判断是否都小于2012,返回值是布尔
// myCars.ForEach(p => p.StickerPrice -=3000);//List内置的ForEach用法,这里是把全部价格都减3000
//myCars.ForEach(p => Console.WriteLine("{0} {1:C}",p.VIN,p.StickerPrice));//同上,一行代码输出内容。
//Console.WriteLine(myCars.Exists(p => p.Model == "745li"));判断型号为“745li”的车是否存在,输出布尔型
//Console.WriteLine(myCars.Sum(p => p.StickerPrice));//累加
Console.WriteLine(myCars.GetType());//用来演示具体类型的
/* foreach (var car in paixv)
{
Console.WriteLine("{0} {1} {2}",car.Model,car.VIN,car.Year);
}//普通的For each
*/
Console.ReadLine();
}
}
class Car
{
public string VIN { get; set; }
public string Make { get; set; }
public string Model { get; set; }
public int Year { get; set; }
public double StickerPrice { get; set; }
}
}
Bob在结尾的时候提到了匿名类型。简单说一下,匿名类型就是没有声明类、变量之类的类型。编译器会自动识别,通常会把同一属性,同一方法的变量归为同一类型。反之亦然。详情参阅:C#匿名类型。