欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#十种语法糖

程序员文章站 2022-06-10 15:26:27
语法糖指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。需要声明的是“语法糖”这个词绝非贬义词,它...

语法糖

指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。
需要声明的是“语法糖”这个词绝非贬义词,它可以给我们带来方便,是一种便捷的写法,编译器会帮我们做转换,而且可以提高开发编码的效率,在性能上也不会带来损失。

一、自动属性

以前:手写私有变量+公有属性
现在:声明空属性,编译器自动生成对应私有成员字段。

写法:输入prop ,连续按两次tab键,自动生成属性。

 1         /// <summary>
 2         /// 自动属性
 3         /// </summary>
 4         public string name { get; set; }
 5 
 6         /// <summary>
 7         /// 传统属性写法
 8         /// </summary>
 9         private string _loginname;
10 
11         public string loginname
12         {
13             get { return _loginname; }
14             set { _loginname = value; }
15         }

 二、隐式类型(var)

var定义变量有以下四个特点:
程序员在声明变量时可以不指定类型,由编译器根据值来指定类型
1、必须在定义时初始化
2、一旦初始化完成,就不能再给变量赋与初始值不同类型的值了
3、var要求是局部变量
4、使用var定义变量和object不同,它在效率上和使用强类型方式定义变量完全一样

注意:
a.隐式类型在定义时必须初始化
例如:var name; 错  var name="tom";正确
b.可以用同类型的其他隐式类型变量来初始化新的隐式类型变量
例如:var v=1;
      var v2=v;
c.也可以用同类型的字面量来初始化隐式类型变量
例如: var v3="hello";
      v3="world";
d.隐式类型局部变量还可以初始化数组而不指定类型
例如: var array=new int[]{1,2,3,4,5}; (注意:赋值运算符左边没有方括号)
e.编译器可以根据变量的初始值“推断”变量的类型
例如: var number=0;  编译后就变成了  int number =0;

三、参数默认值和命名参数

    c#方法的可选参数是.net 4.0最新提出的新的功能,对应简单的重载可以使用可选参数和命名参数混合的形式来定义方法,这样就可以很高效的提高代码的运行效率
    设计一个方法的参数时,可以部分或全部参数分配默认值。调用其方法时,可以重新指定分配了默认值的参数,也可以使用默认值。重新指定分配默认值的参数时,可以显式地为指定参数名称赋值;隐式指定的时候,是根据方法参数的顺序,靠c#编译器的推断。

使用的指导原则:
1、可以为方法和有参属性指定默认值
2、有默认值的参数,必须定义在没有默认值的参数之后
3、默认参数必须是常量
4、ref和out参数不能指定默认值

 1  public class user
 2     {
 3         /// <summary>
 4         /// 自动属性
 5         /// </summary>
 6         public string name { get; set; }
 7 
 8         public string loginname { get; set; }
 9 
10         public int age { get; set; }
11 
12         public string  address { get; set; }
13 
14         public string  password { get; set; }
15 
16         //构造函数重载
17         public user(string name)
18         {
19             this.name = name;
20         }
21 
22         public user(string name,string loginname)
23         {
24             this.name = name;
25             this.loginname = loginname;
26         }
27 
28         /// <summary>
29         /// 默认参数
30         /// </summary>
31         /// <param name="name"></param>
32         /// <param name="loginname"></param>
33         /// <param name="age"></param>
34         /// <param name="address"></param>
35         /// <param name="password"></param>
36         public user(string name,string loginname,int age,string address="上海",string password="1234")
37         {
38             this.name = name;
39             this.loginname = loginname;
40             this.age = age;
41             this.address = address;
42             this.password = password;
43         }
44     }
45 
46 使用默认值参数和命名参数
47  class program
48     {
49         static void main(string[] args)
50         {
51             //参数默认值:可以给参数赋值也可以使用参数默认值
52             //1、使用默认值
53             user user = new user("小明","xiaoming",27);
54             console.writeline(user.address);//输出默认值:上海
55 
56             //2、给参数赋值
57             user user2 = new user("小红", "xiaohong", 28,"北京");
58             console.writeline(user2.address);//输出:北京
59 
60             //命名参数:使用默认值参数的时候,指定参数的名称,命名参数要写在所有固定参数的后面
61             //好处:适用于有多个默认值参数的情况,根据命名参数,只修改需要修改的默认值
62             //使用命名参数只修改密码
63             user user3 = new user("小红", "xiaohong", 28,password:"5678");
64             console.writeline(user3.password);//输出:5678
65 
66             console.readkey();
67         }
68     }

输出结果:

C#十种语法糖

四、对象初始化器和集合初始化器

 1  class program
 2     {
 3         static void main(string[] args)
 4         {
 5 
 6             //传统的初始化对象的方式
 7             user zjl = new user();
 8             zjl.name = "周杰伦";
 9             zjl.phone = "12345678956";
10 
11             //使用对象初始化器:{},使用对象初始化器,必须提供一个无参的构造函数,可以只给部分属性初始化
12             user xiaohong = new user()
13             {
14                 name = "小红",
15                 phone = "1232154566",
16                 address = "上海"
17             };
18 
19             console.writeline("姓名:"+xiaohong.name);//输出:小红
20 
21             //集合初始化器
22             list<user> listuser = new list<user>()
23             {
24                 xiaohong,
25                 new user(){name="张三",password="1234",age=12,deptid="0001"},
26                 new user(){name="张四",password="1234",age=16,deptid="0002"},
27                 new user(){name="张五",password="1234",age=29,deptid="0003"},
28                 new user(){name="张六",password="1234",age=18,deptid="0001"},
29                 new user(){name="张七",password="1234",age=12,deptid="0001"}
30             };
31             console.readkey();
32         }
33     }

 五、匿名类和匿名方法

 

匿名类型
有时候你定义的类只是用来封装一些相关的数据,但并不需要相关联的方法、事件和其他自定义的功能。同时,这个类仅仅在当前的应用程序中使用,而不需要在项目间重用。你所需要的只是一个“临时的”类型,现在来看看这个类的定义
internal class oneclass
{
   //定义若干私有数据成员
   //通过属性来封装每个数据成员
}

构建上面的类虽然说不上有多难,但是如果这个类有很多数据成员的话,那么还是要消耗相当时间的。c#3.0提供了匿名类型来轻松完成这个工作。
现在定义一个匿名对象来表示一个人
var apeople=new {pname="张三",page=26,psex="男"};
现在我们就可以使用属性语法获取和设置对象的各个变量
apeople.page=29;
console.writeline("{0} is {1}years old",apeople.pname,apeople.page);
匿名类型的嵌套
    刚刚我们定义了表示一个人的匿名类型,现在我们定义一个表示雇员的嵌套匿名类型:
    var aemployee=new {
        joindate="2012-09-23",
        apeople=new {pname="张三",page=26,psex="男"},
        title=manager
    };

匿名类型的限制:
1、匿名类型不支持事件、自定义方法和自定义重写
2、匿名类型是隐式封闭的
3、匿名类型的实例创建只使用默认构造函数
4、匿名类型没有提供可供控制的类名称(使用var定义的)

匿名方法
普通方法定义方式,因为方法的存在是为了复用一段代码,所以一般会给方法取个名字,这个方法的引用就可以通过“方法名”调用
匿名方法:
但是有的方法,不需要复用,仅仅是使用一次就够了,所以不需要方法名,这种方法就叫做匿名方法。
匿名方法必须结合委托使用。(潜在的意思就是:尽管没有方法名了,但方法的指针还是存放了某个委托对象中)
注意:
1、在编译后,会为每个匿名方法创建一个私有的静态方法,然后将此静态方法传给委托对象使用
2、匿名方法编译后会生成委托对象,生成方法,然后把方法装入委托对象,最后赋值给声明的委托变量
3、匿名方法可以省略参数,编译的时候会自动为这个方法按照委托签名的参数添加参数

 1   public class test
 2     {
 3         public static void testfive()
 4         {
 5             //匿名类型:只能使用一次,仅能在当前的项目中使用
 6             var apeople = new { pname = "张三", page = 26, paddress = "美国" };
 7             //嵌套匿名类型
 8             var aemployee = new
 9             {
10                 jiondate = datetime.now,
11                 salary = 8000,
12                 apeople = new { pname = "张三", page = 26, paddress = "美国" }
13             };
14 
15             console.writeline(aemployee.apeople.pname);//输出:张三
16 
17             console.readkey();
18         }
19 
20         public static void test()
21         {
22             //不能使用匿名类型apeople,apeople是局部
23             console.writeline(apeople.pname);//错误
24         }
25     }

匿名方法


 1 class program
 2     {
 3         /// <summary>
 4         /// 声明委托
 5         /// </summary>
 6         /// <param name="s"></param>
 7         delegate void printer(string s);
 8         public delegate void printemployee(user u);
 9 
10         static void main(string[] args)
11         {
12             //匿名方法:必须结合委托使用
13             printer p = delegate(string s)
14             {
15                 console.writeline(s);
16             };
17             //使用匿名方法
18             p("hello world");
19 
20             list<user> listuser = new list<user>()
21             {
22                 new user(){name="张三",password="1234",age=12,deptid="0001"},
23                 new user(){name="张四",password="1234",age=16,deptid="0002"},
24                 new user(){name="张五",password="1234",age=29,deptid="0003"},
25                 new user(){name="张六",password="1234",age=18,deptid="0001"},
26                 new user(){name="张七",password="1234",age=12,deptid="0001"}
27             };
28 
29             //匿名方法只使用一次
30             changeuserpwd(listuser, delegate(user u) {
31 
32                 console.writeline(u.name+"的新密码是:"+u.password);
33             });
34             //使用lambda表达式
35             changeuserpwd(listuser, u=>
36             {
37                 console.writeline(u.name + "的新密码是:" + u.password);
38             });
39             console.readkey();
40         }
41 
42         /// <summary>
43         /// 批量修改用户的密码并输出修改以后的密码
44         /// </summary>
45         /// <param name="list"></param>
46         /// <param name="callback"></param>
47         public static void changeuserpwd(list<user> list, printemployee callback)
48         {
49             int i = 0;
50             foreach (user u in list)
51             {
52                 u.password = u.password + i.tostring();
53                 i += 2;
54                 callback(u);
55             }
56         }        
57     }

 


 六、扩展方法

为什么要有扩展方法,就是为了在不修改源码的情况下,为某个类增加新的方法。
语法:
定义静态类,并添加public的静态方法,第一个参数代表扩展方法的扩展类。它必须放在一个非嵌套、非泛型的静态类中(的静态方法);它至少有一个参数;第一个参数必须附加this关键字;第一个参数不能有任何其他修饰符(out/ref).第一个参数不能是指针类型。
注意:
1、c#只支持扩展方法,不支持扩展属性、扩展事件等;
2、方法名无限制,第一个参数必须带this,表示要扩展的类型;
3、扩展方法的命名空间可以使用namespace system,但不推荐;
4、定义扩展方法的类必须是静态类;
5、扩展方法虽然是public的静态方法,但是生成以后是实例方法,使用时需要先实例化对象,通过对象.方法名进行调用扩展方法;

 1 /// <summary>
 2     /// 静态类:对convert进行扩展,增加一个将string转换成int的方法
 3     /// </summary>
 4     public static class convertextension
 5     {
 6         /// <summary>
 7         /// 静态方法:this 表示针对this后面的类型进行扩展
 8         /// </summary>
 9         /// <param name="s"></param>
10         /// <returns></returns>
11         public static int converttoint(this convert convert,string s)
12         {
13             int i;
14             if (int.tryparse(s, out i))
15             {
16                 return i;
17             }
18             else
19             {
20                 return 0;
21             }
22         }
23     }
24 
25 class program
26     {
27         static void main(string[] args)
28         {
29             //使用扩展方法:扩展方法虽然是public的静态方法,但是生成以后是实例方法,使用时需要先实例化对象,通过对象.方法名进行调用扩展方法
30             //扩展方法所在命名空间和使用代码的命名空间必须相同 扩展方法必须是静态类
31             convert convert = new convert();
32             int i= convert.converttoint("abc");
33 
34             console.writeline(i);//输出:0
35 
36             //方法2
37             int j= convertextension.converttoint(convert, "2");
38             console.writeline(j);//输出:2
39 
40             console.readkey();
41         }
42     }

七、内置泛型委托

action<t>
可以使用action<t>委托以参数形式传递方法,而不用显示声明自定义的委托。封装的方法必须与此委托定义的方法签名相对应,也就是说,封装的方法必须具有一个通过值传递给它的参数,并且不能有返回值。
通常,这种方法用于执行某个操作。

 1 /// <summary>
 2     /// list扩展方法
 3     /// </summary>
 4     public static class listextend
 5     {
 6         //声明自定义泛型委托
 7         public delegate void printt<t>(t t);
 8 
 9         public static void teach<t>(this list<t> list, printt<t> pt)
10         {
11             foreach (t t in list)
12             {
13                 pt(t);
14             }
15         }
16     }
17 
18 
19 class program
20     {
21         
22         static void main(string[] args)
23         {
24             list<user> listuser = new list<user>()
25             {
26                 new user(){name="张三",password="1234",age=12,deptid="0001"},
27                 new user(){name="张四",password="1234",age=16,deptid="0002"},
28                 new user(){name="张五",password="1234",age=29,deptid="0003"},
29                 new user(){name="张六",password="1234",age=18,deptid="0001"},
30                 new user(){name="张七",password="1234",age=12,deptid="0001"}
31             };
32 
33             list<dept> listdept = new list<dept>()
34             {
35                 new dept(){deptid="0001",deptname="人事部",pepnum=10},
36                  new dept(){deptid="0002",deptname="财务部",pepnum=7},
37                   new dept(){deptid="0003",deptname="行政部",pepnum=15}
38             };
39 
40 
41             #region 使用自定义委托
42             
43             //打印所有用户信息
44             listuser.teach(printuser);
45 
46             listdept.teach(printdept); 
47             
48             #endregion
49 
50 
51             #region 使用内置泛型委托
52 
53             listuser.foreach(printuser);
54             //使用匿名方法
55             listuser.foreach(delegate(user u) { console.writeline(u.name + " " + u.password + " " + u.phone); });
56 
57             //使用lambda表达式
58             listuser.foreach(p=>console.writeline(p.name+" "+p.password+" "+p.phone));
59 
60             listdept.foreach(new action<dept> (delegate(dept d)
61             {
62                 console.writeline(d.deptid + " " + d.deptname + " " + d.pepnum);
63             }));
64 
65             #endregion
66 
67             console.readkey();
68         }
69 
70         /// <summary>
71         /// 打印一个用户信息
72         /// </summary>
73         /// <param name="u"></param>
74         public static void printuser(user u)
75         {
76             console.writeline(u.name+" "+u.password+" "+u.phone);
77         }
78 
79         /// <summary>
80         /// 打印一个部门信息
81         /// </summary>
82         /// <param name="d"></param>
83         public static void printdept(dept d)
84         {
85             console.writeline(d.deptid+" "+d.deptname+" "+d.pepnum);
86         }
87     }

predicate<t>
表示定义一组条件并确定指定对象是否符合这些条件的方法。
此委托由array和list<t>类的几种方法使用,用于在集合中搜索元素。返回值为bool类型

 1  public static class extend
 2     {
 3         //自定义泛型委托
 4         public delegate bool checkdelegate<t>(t t);
 5         public static list<t> myfind<t>(this list<t> list, checkdelegate<t> match)
 6         {
 7             list<t> newlist = new list<t>();
 8             foreach (t item in list)
 9             {
10                 if (match(item))
11                 {
12                     newlist.add(item);
13                 }
14             }
15             return newlist;
16         }
17     }
18 
19 
20 class program
21     {
22         static void main(string[] args)
23         {
24             list<user> listuser = new list<user>()
25             {
26                 new user(){name="张三",password="1234",age=12,deptid="0001"},
27                 new user(){name="张四",password="1234",age=16,deptid="0002"},
28                 new user(){name="张五",password="1234",age=29,deptid="0003"},
29                 new user(){name="张六",password="1234",age=18,deptid="0001"},
30                 new user(){name="张七",password="1234",age=12,deptid="0001"}
31             };
32 
33             list<dept> listdept = new list<dept>()
34             {
35                 new dept(){deptid="0001",deptname="人事部",pepnum=10},
36                  new dept(){deptid="0002",deptname="财务部",pepnum=7},
37                   new dept(){deptid="0003",deptname="行政部",pepnum=15}
38             };
39             
40             //使用内置predicate委托
41            list<user> newlistuser=  listuser.findall(new predicate<user>(delegate(user u){return u.age>40;}));
42 
43             //使用自定义泛型委托
44            list<user> list = listuser.myfind(match);
45            foreach (user u in list)
46            {
47                console.writeline(u.name + " " + u.password + " " + u.phone); 
48            }
49            console.readkey();
50         }
51 
52         static bool match(user u)
53         {
54             if (u.age > 15)
55             {
56 
57                 return true;
58             }
59             return false;
60         }
61     }

func 返回值类型可以自定义

 1 class program
 2     {
 3         static void main(string[] args)
 4         {
 5             list<user> listuser = new list<user>()
 6             {
 7                 new user(){name="张三",password="1234",age=12,deptid="0001"},
 8                 new user(){name="张四",password="1234",age=16,deptid="0002"},
 9                 new user(){name="张五",password="1234",age=29,deptid="0003"},
10                 new user(){name="张六",password="1234",age=18,deptid="0001"},
11                 new user(){name="张七",password="1234",age=12,deptid="0001"}
12             };
13 
14             list<dept> listdept = new list<dept>()
15             {
16                 new dept(){deptid="0001",deptname="人事部",pepnum=10},
17                  new dept(){deptid="0002",deptname="财务部",pepnum=7},
18                   new dept(){deptid="0003",deptname="行政部",pepnum=15}
19             };
20 
21             //可以自定义func返回值类型
22             list<int> newlist= listuser.select(new func<user, int>(delegate(user u) { return u.age; })).tolist();
23             list<int> list = listuser.select(p => { return p.age; }).tolist();
24             newlist.foreach(p => console.writeline(p));
25 
26             //根据用户信息得到员工信息
27             list<employee> listemploy= listuser.select(new func<user, employee>(delegate(user u)
28                 {
29                     employee e = new employee();
30                     if (u.age > 15)
31                     {
32                         e.name = u.name;
33                         e.phone = u.phone;
34                         e.salary = 5000;
35                         return e;
36                     }
37                     else
38                     {
39                         return null;
40                     }
41 
42                     
43                 })).tolist();
44             listemploy.foreach(p =>
45             {
46                 if (p != null)
47                 {
48                     console.writeline(p.name+" "+p.salary);
49                 }
50               
51             });
52 
53             console.readkey();
54         }
55     }

八、lambda表达式

lambda表达式是比匿名方法更简洁的一种匿名方法语法

最基本的lambda表达式语法:
{参数列表}=>{方法体}
例如:
(int x)=>{returm x+1}
说明:
1、参数列表中的参数类型可以是明确类型或推断类型
2、如果是推断类型,则参数的数据类型将由编译器根据上下文自动推断出来

如果参数列表只包含一个推断类型参数时:
参数列表=>{方法体}
前提:x的数据类型可以根据上下文推断出来
 x =>{returm x+1}

如果方法体只包含一条语句时:
{参数列表}=>表达式
{int x} => x+1;

lambda表达式示例:
1、多参数,推断类型参数列表,表达式方法体
(x,y) => x*y
2、无参数,表达式方法体
() => console.writeline()
3、多参数,推断类型参数列表,多语句方法体,需要使用{}
(x,y) => {console.writeline(x);console.writeline(y)}

lambda表达式缩写推演
new func<string,int>(delegate(string str){return str.length;});//内置委托
delegate(string str){return str.length;}//匿名方法
(string str)=>{return str.length};//lambda表达式
(str)=>str.length;//让编译器推断类型
str=>str>length;//去掉不必要的括弧

 1   #region lambda表达式
 2 
 3             //标准语法
 4             mydelegate my1 = (string name) => { return "lambda表达式:hello" + name; };
 5             console.writeline(my1("tom"));
 6 
 7             //或者(仅有一个参数) 参数列表只包含一个推断类型参数
 8             mydelegate my2 = name => { return "lambda表达式:hello" + name; };
 9             console.writeline(my2("tom"));
10 
11             //或者(方法体只有一条语句)
12             mydelegate my3 = name => "lambda表达式:hello" + name;
13             console.writeline(my3("tom"));
14 
15             #endregion

九、标准查询运算符

标准查询运算符:定义在system.linq.enumerable类中的50多个为ienumerable<t>准备的扩展方法,这些方法用来对它操作的集合进行查询筛选。
筛选集合where:需要提供一个带bool返回值的“筛选器”,从而标明集合中某个元素是否应该被返回。
查询投射:返回新对象集合ienumerable<tsource> select()
统计数量int count()
多条件排序 orderby().thenby().thenby()
集合连接 join()

 1 class program
 2     {
 3         static void main(string[] args)
 4         {
 5             list<user> listuser = new list<user>()
 6             {
 7                 new user(){name="张三",password="1234",age=12,deptid="0001"},
 8                 new user(){name="张四",password="1234",age=16,deptid="0002"},
 9                 new user(){name="张五",password="1234",age=29,deptid="0003"},
10                 new user(){name="张六",password="1234",age=18,deptid="0001"},
11                 new user(){name="张七",password="1234",age=12,deptid="0001"}
12             };
13 
14             list<dept> listdept = new list<dept>()
15             {
16                 new dept(){deptid="0001",deptname="人事部",pagenum=10},
17                 new dept(){deptid="0002",deptname="财务部",pagenum=10},
18                 new dept(){deptid="0003",deptname="行政部",pagenum=10}
19             };
20 
21             //1.where
22             list<user> newlistuser = listuser.where(p => p.age>12).tolist();
23             console.writeline("所有用户姓名");
24             listuser.foreach(p=>console.writeline(p.name));
25             console.writeline("年龄大于12的用户姓名");
26             newlistuser.foreach(p=>console.writeline(p.name));
27 
28             //2.order by 排序  多条件排序:先按照年龄降序排序,在安排phone降序排序,最后按照loginname升序排序
29             list<user> list1 = listuser.orderbydescending(p => p.age).thenbydescending(p => p.phone).thenby(p => p.loginname).tolist();
30 
31             //3.join:连接查询
32             //返回值是非匿名类:返回值是userdept类型
33             list<userdept> uds = listuser.join(listdept, u => u.deptid, d => d.deptid,
34                  (u, d) => new userdept() { username = u.name, loginname = u.loginname, deptname = d.deptname }).tolist();
35             //循环输出
36             uds.foreach(p=>console.writeline(p.username));
37 
38             //返回值是匿名类:用var推断类型接收返回值
39             var udvar = listuser.join(listdept, u => u.deptid, d => d.deptid,
40                  (u, d) => new { username = u.name, loginname = u.loginname, deptname = d.deptname }).tolist();
41             //循环输出
42             udvar.foreach(p => console.writeline(p.username));
43 
44             #region 4.0 group by 分组
45 
46             //4.1 按照集合中的用户的部门编号进行分组
47             ienumerable<igrouping<string, user>> usergroup = listuser.groupby(p => p.deptid);
48 
49             foreach (igrouping<string, user> group in usergroup)
50             {
51                 console.writeline("部门编号:" + group.key);
52                 foreach (user user in group)
53                 {
54                     console.writeline(user.name + "-" + user.phone + "-" + user.loginname);
55                 }
56 
57                 console.writeline("--------------------------------");
58             }
59             #endregion
60 
61             #region 5.0 分页:skip+take  skip:跳过 take:取
62             
63             //分页前提:数据源按照一定的列进行排序
64             list<user> listsource = listuser.orderby(p => p.name).tolist();
65             foreach (user user in listsource)
66             {
67                 console.writeline(user.name);
68             }
69 
70             console.writeline("--------------");
71             //取第一页数据,每页显示2条数据
72             list<user> list = getpagelistbyindex(listuser, 1, 2);
73             //输出分页结果
74             foreach (user user in list)
75             {
76                 console.writeline(user.name);
77             }
78 
79             #endregion
80 
81             console.readkey();
82         }
83 
84         /// <summary>
85         /// 根据页码提取当页数据
86         /// </summary>
87         /// <param name="listsource">要分页的数据</param>
88         /// <param name="pageindex">页码</param>
89         /// <param name="pagesize">每页要显示的条数</param>
90         /// <returns></returns>
91         static list<user> getpagelistbyindex(list<user> listsource, int pageindex, int pagesize)
92         {
93             return listsource.skip((pageindex - 1) * pagesize).take(pagesize).tolist();
94         }
95     }

十、linq

linq:语言集成查询
linq是一组语言特性和api,使得你可以使用统一的方式编写各种查询。查询的对象包括xml、对象集合、sql server数据库等等。
linq to objects:主要负责对象的查询
linq to xml:主要负责xml的查询
linq to ado.net:主要负责数据库的查询
  linq to sql
  linq to dataset
  linq to entities

 

linq查询的两种方式:
1、查询方法方式:主要利用system.linq.enumerable类中定义的扩展方法和lambda表达式进行查询
2、查询语句方式:一种更接近sql语法的查询方式

查询语句vs查询方法
1、clr本身并不理解查询语句,它只理解查询方法
2、编译器负责在编译时将查询语句翻译成查询方法
3、大部分查询方法都有对应的查询语句形式:select()对应select、orderby()对应orderby
4、部分查询方法目前在c#中还没有对应的查询语句,如:count()和max()这时只能采用以下替代方案:
   查询方法
   查询语句+查询方法的混合方式

  1  class program
  2     {
  3         //声明委托
  4         public delegate string mydelegate(string name);
  5 
  6         static void main(string[] args)
  7         {
  8             //创建int类型数组,查找其中的偶数并降序排序输出
  9             int[] arrays = { 5, 2, 0, 66, 4, 32, 7, 1 };
 10 
 11             #region  使用循环实现
 12 
 13             list<int> list = new list<int>();
 14             foreach (int i in arrays)
 15             {
 16                 if (i % 2 == 0)
 17                 {
 18                     list.add(i);
 19                 }
 20             }
 21             //排序
 22             list.sort();
 23             //反转
 24             list.reverse();
 25 
 26             console.writeline(string.join(",", list));
 27 
 28 
 29             #endregion
 30 
 31             #region 使用linq实现
 32             //查询方法方式
 33             var intnew = arrays.where(p => p % 2 == 0)
 34                 .select(p => p)
 35                 .orderbydescending(p => p).tolist();
 36 
 37             console.writeline(string.join(",", intnew));
 38 
 39             //查询语句方式
 40             var even = from number in arrays
 41                        where number % 2 == 0
 42                        orderby number descending
 43                        select number;
 44             #endregion
 45 
 46             //linq新特性
 47 
 48             #region 类型推断
 49             //类型推断  注意:不要乱用,仅用在linq中
 50             var b = true;
 51             if (b)
 52             {
 53                 console.writeline("true");
 54             }
 55             #endregion
 56 
 57             #region 扩展方法
 58             //扩展方法 扩展方法所在命名空间和使用代码的命名空间必须相同 扩展方法必须是静态类
 59             string s = "abc";
 60             int a = s.toint();//方法图标有一个向下的箭头,表示是扩展方法
 61             console.writeline(a);
 62 
 63             object obj = "sdsf";
 64            double d=  obj.todouble();
 65 
 66            console.writeline(d);
 67             #endregion
 68           
 69 
 70             #region 对象初始化器
 71             //集合初始化器
 72             contact con = new contact() 
 73            {firstname="tom",lastname="jerry",email="tom@163.com" };
 74 
 75             console.writeline(con.email);
 76             #endregion
 77 
 78             #region 集合初始化器
 79 
 80             list<contact> listcontact = new list<contact>() 
 81             {
 82               new contact(){firstname="tom",lastname="tack",email="aaa"},
 83               new contact(){firstname="tom",lastname="jerry",email="bbb"}
 84             };
 85 
 86             console.writeline(listcontact[0].email);
 87             #endregion
 88 
 89             #region 匿名类型
 90 
 91             var item = new {productname="iphone",price=4000 };
 92             string info = item.productname + "..." + item.price;
 93             console.writeline(info);
 94 
 95             #endregion
 96 
 97             //定义委托类型的变量
 98             mydelegate my = new mydelegate(hello);//mydelegate my=hello
 99             //调用委托
100             string strname = my("tom");
101             console.writeline(strname);
102 
103 
104             #region 匿名方法(只用一次)
105             mydelegate my2 = delegate(string str)
106             {
107                 return "匿名方法:hello" + str;
108             };
109 
110             //调用
111             string name= my2("tom");
112             console.writeline(name);
113             #endregion
114 
115             #region lambda表达式
116 
117             //标准语法
118             mydelegate my1 = (string str) => { return "lambda表达式:hello" + str; };
119             console.writeline(my1("tom"));
120 
121             //或者(仅有一个参数) 参数列表只包含一个推断类型参数
122             mydelegate mydel = p => { return "lambda表达式:hello" + p; };
123             console.writeline(my2("tom"));
124 
125             //或者(方法体只有一条语句)
126             mydelegate my3 = p => "lambda表达式:hello" + p;
127             console.writeline(my3("tom"));
128 
129             #endregion
130 
131             //linq
132             //两种查询方式
133             //select
134             int[] intarray = { 1,2,3,6,4,90,65,44,9};
135 
136             //1、查询方法方式 p:指的是intarray数组中的每一个元素
137             var var1 = intarray.select(p => p + 1);
138             console.writeline(string.join(",", var1));
139 
140             //2、查询语句方式
141             var var2 = from p in intarray select p + 1;
142             console.writeline(string.join(",", var1));
143             
144             
145             //where
146             //查询方法
147             var var3 = intarray.where(p => p % 2 == 0);//选择数组中的偶数
148             //查询语句(一般以select结尾)
149             var3 = from number in intarray
150                    where number % 2 == 0
151                    select number;
152             
153             //多个条件(刷选出数组中大于10的偶数)
154             //查询方法1
155             var3 = intarray.where(p => p % 2 == 0 && p > 10);
156             //查询方法2:使用自定义谓语条件查询
157             var3 = intarray.where(p => getcondition(p));
158 
159             //查询语句1
160             var3 = from number in intarray
161                    where number % 2 == 0 && number > 10
162                    select number;
163             //查询语句2
164             var3 = from number in intarray
165                    where getcondition(number)
166                    select number;
167             console.writeline(string.join(",", var3));
168 
169 
170             //建立一个contact类型的集合,查找firstname="tom" && email=""的联系人的lastname,使用4种方式查询
171             list<contact> mycontact = new list<contact>() 
172             {
173               new contact(){firstname="tom",lastname="jorry",email="tom@163.com"},
174               new contact(){firstname="tom",lastname="jack",email="jack@163.com"},
175               new contact(){firstname="tom",lastname="jerry",email="jerry@163.com"}
176             };
177 
178             //查询方法
179             var var4 = mycontact.where(p => p.firstname == "tom" && p.email == "tom@163.com");
180             var4 = mycontact.where(p => getcontact(p));
181 
182             //查询语句
183             var4 = from p in mycontact where p.firstname == "tom" && p.email == "tom@163.com" select p;
184             var4 = from p in mycontact where getcontact(p) select p;
185             foreach(contact contact in var4)
186             {
187                 console.writeline(contact.lastname);
188             }
189 
190             //删除重复元素,没有对应的查询语句
191             int[] ints = { 1,1,2,3,4,0};
192             var var5 = ints.distinct();
193             console.writeline(string.join(",",var5));
194 
195             //排序
196             int[] intarrays = { 1,2,4,3,7,8,0};
197             var var6 = intarrays.orderby(i => i);
198             var6 = intarrays.orderbydescending(i => i);
199             //级联调用
200             var6 = intarrays.where(i => i % 2 == 0).orderby(i => i);
201             var6 = from i in intarrays where i % 2 == 0 
202                    orderby i select i;//正序排序
203             var6 = from i in intarrays where i % 2 == 0 
204                    orderby i descending select i;//倒序排序
205             //查询方法+查询语句,混合使用
206             var6 = (from i in intarrays where i % 2 == 0 select i).orderby(i => i);
207             console.writeline(string.join(",", var6));
208 
209             //复杂查询
210             list<employee> listemployee = new list<employee>() 
211             {
212                new employee(){
213                    firstname="唐僧",
214                    lastname="玄奘",
215                    sex="男",
216                    age=30,   
217                    country="大唐"
218                },
219                 new employee(){
220                    firstname="白骨精",
221                    lastname="晶晶",
222                    sex="女",
223                    age=200,   
224                    country="古墓"
225                },
226                 new employee(){
227                    firstname="孙悟空",
228                    lastname="行者",
229                    sex="男",
230                    age=500,   
231                    country="傲来国"
232                },
233                 new employee(){
234                    firstname="紫霞",
235                    lastname="仙子",
236                    sex="女",
237                    age=100,   
238                    country="天界"
239                }              
240             };
241 
242             //分组,按照性别分组
243             var var7 = from p in listemployee group p by p.sex;
244             var7 = listemployee.groupby(p => p.sex);
245             foreach (var group in var7)
246             {
247                 console.writeline("分组:"+group.key);
248                 foreach (var v in group)
249                 {
250                     console.writeline(v.firstname);
251                 }
252             }
253             console.readkey();
254         }
255 
256         static bool getcontact(contact item)
257         {
258             if (item.firstname == "tom" && item.email == "tom@163.com")
259                 return true;
260             else
261                 return false;
262         }
263 
264         static bool getcondition(int i)
265         {
266             if (i % 2 == 0 && i > 10)
267                 return true;
268             else
269                 return false;
270         }
271 
272         static string hello(string name)
273         {
274             return "hello" + name;
275         }
276     }

查询语句

 1 class program
 2     {
 3         static void main(string[] args)
 4         {
 5             list<user> listuser = new list<user>()
 6             {
 7                 new user(){name="张三",password="1234",age=12,deptid="0001"},
 8                 new user(){name="张四",password="1234",age=16,deptid="0002"},
 9                 new user(){name="张五",password="1234",age=29,deptid="0003"},
10                 new user(){name="张六",password="1234",age=18,deptid="0001"},
11                 new user(){name="张七",password="1234",age=12,deptid="0001"}
12             };
13 
14               list<dept> listdept = new list<dept>()
15             {
16                 new dept(){deptid="0001",deptname="人事部",pagenum=10},
17                 new dept(){deptid="0002",deptname="财务部",pagenum=10},
18                 new dept(){deptid="0003",deptname="行政部",pagenum=10}
19             };
20 
21             //1、从老集合中查询每一个元素存放到新集合
22             var newlist = from p in listuser select p;
23 
24             //2、带where条件
25             var list = from p in listuser where p.age > 12 && p.address == "上海" select p;
26 
27             //3、orderby排序:按照姓名、年龄升序排序
28             var newlistuser = from p in listuser orderby p.name orderby p.age ascending  select p;
29 
30             //4、join
31             var joinresult = from u in listuser
32                              join d in listdept
33                              on u.deptid equals d.deptid
34                              select new {username = u.name, loginname = u.loginname, deptname = d.deptname  };
35             //遍历
36             foreach (var item in joinresult)
37             {
38                 console.writeline(item.deptname);
39             }
40 
41             //5、 group by 分组查询
42             var grouplist = from u in listuser group u by u.deptid;
43             //遍历
44             foreach (var group in grouplist)
45             {
46                 console.writeline(group.key);
47                 foreach (var item in group)
48                 {
49                     console.writeline(item.tostring());
50                 }
51             }
52 
53             console.readkey();
54         }
55     }