LINQ To SQL深入学习系列之一(C#3.0为LINQ的加强之一)

简介:

本文例子大部分来自于(Apress pro linq)

为了使LINQ可以无缝的和C#语言整合在一起,微软对C#3.0加入了些新功能,这里主要介绍和LINQ相关的加强。

1、var关键字,集合初始化以及匿名类型

2、Lambda 表达式

3、部分(Partial )方法
4、扩展方法

5、表达式树
 1、var关键字,集合初始化以及匿名类型

var:
可以赋予局部变量推断“类型”var 而不是显式类型。var 关键字指示编译器根据初始化语句右侧的表达式推断变量的类型。推断类型可以是内置类型、匿名类型、用户定义类型、.NET Framework 类库中定义的类型或任何表达式。var只是表示由编译器确定和分配最适当的类型。和javascript中的var的概念不同.例如:var i = 5;编译完之后i就是一个整型,和int i=5;没有任何区别.在很多情况下,var 是可选的,它只是提供了语法上的便利。
请看如下例子:
var i = 5;//int
var j = 23.56;//double
var k = "C Sharp";//string
var x;//错误
var y = null;//错误
var z = { 1, 2, 3 };//错误

 

对象和集合初始值设定项:

 

ContractedBlock.gif Code


User user = new User();
user.Id = 1;
user.Name = “lfm";
user.Age = 22;
在VS2008中,编译器会自动地生成合适的属性setter代码,使得原来几行的属性赋值操作可以在一行完成。我们可以这样简化:像这样,对象初始化器由一系列成员对象组成,其对象必须初始化,用逗号间隔,使用{}封闭。
User user = new User { Id = 1, Name = “lfm", Age = 22 };

又例如,我把二个人加到一个基于泛型的类型为User的List集合中:
List<User> user = new List<User>{
    new User{Id=1,Name=“lfm",Age=22},
    new User{Id=2,Name=“tmx",Age=25},
};

 

匿名类型:
匿名类型提供了一种方便的方法,可用来将一组只读属性封装到单个对象中,而无需首先显式定义一个类型。类型名由编译器生成,并且不能在源代码级使用。这些属性的类型由编译器推断。

匿名类型允许定义行内类型,无须显式定义类型。在将匿名类型分配给变量时,必须使用 var 构造初始化该变量。
//属性也不需要申明,这些属性的类型由编译器推断
var p1 = new { Id = 1, Name = “lfm", Age = 22 };
var p2 = new { Id = 2, Name = “tmx", Age = 25 };
p1 = p2;//p1,p2结构相同,可以互相赋值
在这里编译器会认为p1,p2相当于: 
public class SomeType
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}
备注(from msdn)
匿名类型是直接从对象派生的引用类型。尽管应用程序无法访问匿名类型,但编译器仍会为其提供一个名称。从公共语言运行库的角度来看,匿名类型与任何其他引用类型没有什么不同。
如果两个或更多个匿名类型以相同的顺序具有相同数量和种类的属性,则编译器会将这些匿名类型视为相同的类型,并且它们共享编译器生成的相同类型信息。
匿名类型具有方法范围。若要向方法边界外部传递一个匿名类型或一个包含匿名类型的集合,必须首先将匿名类型强制转换为对象。但是,这会使匿名类型的强类型化无效。如果必须存储查询结果或者必须将查询结果传递到方法边界外部,请考虑使用普通的命名结构或类而不是匿名类型。

 

2、Lambda 表达式

在c#3.0中微软加入了“Lambda 表达式”,“Lambda 表达式”的概念最早是数学家Alonzo Church在1936年提出的,早在LISP语言中就已经得到应用。这些表达式提供了简短的语法来表达一个运算法则。在C#3.0中“Lambda 表达式”是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托或表达式目录树类型。在我们详细讲解“Lambda 表达式”之前,我们先来了解一下“Lambda 表达式”出现的原因。
我们假设这样一个场景,我们希望有这样一个函数,对一个整型数组进行过滤,而过滤得条件在编写函数时还不知道,直到使用这个
函数的时候可以根据当前的情况编写过滤条件函数,大家一看到这个场景可能马上想到,可以使用委托阿。ok,代码如下:

复制代码
  public   class  Common
    {
        
public   delegate   bool  IntFilter( int  i);
        
public   static   int [] FilterArrayOfInts( int [] ints, IntFilter filter)
        {
            ArrayList aList 
=   new  ArrayList();
            
foreach  ( int  i  in  ints)
            {
                
if  (filter(i))
                {
                    aList.Add(i);
                }
            }
            
return  (( int [])aList.ToArray( typeof ( int )));
        }
    }
复制代码

 

 

复制代码
public   class  Application
    {
        
public   static   bool  IsOdd( int  i)
        {
            
return  ((i  &   1 ==   1 );
        }
    }
static   void  Main( string [] args)
        {
            
int [] nums  =  {  1 2 3 4 5 6 7 8 9 10  };
            
int [] oddNums  =  Common.FilterArrayOfInts(nums, Application.IsOdd);
            
foreach  ( int  i  in  oddNums)
                Console.WriteLine(i);
        }
复制代码

 

  结果为:

1
3
5
7
9

看了这段代码之后,大家可能会觉得这个实现可能不够好,这里的IsOdd函数可能只用这么一次,并且也太简单了,不值得当成一个函数来用,于是我们想到了C#2.0的匿名委托,实现代码如下:

 

复制代码
static   void  Main( string [] args)
        {
            
int [] nums  =  {  1 2 3 4 5 6 7 8 9 10  };
            
int [] oddNums  =
            Common.FilterArrayOfInts(nums, 
delegate ( int  i) {  return  ((i  &   1 ==   1 ); });
            
foreach  ( int  i  in  oddNums)
                Console.WriteLine(i);
}
复制代码

 

 恩,这段代码似乎相当棒了,解决了我刚才说的所有问题,但是看起来好象不够简洁,也比较难懂些。我希望有一个更好的方式来解决这个问题。
我们先来看看“Lambda 表达式”的用法,所有 Lambda 表达式都使用 Lambda 运算符 =>,该运算符读为“goes to”。该 Lambda 运算符的左边是输入参数(如果有),右边包含表达式或语句块。Lambda 表达式 x => x * x 读作“x goes to x 乘x”其意义就是输入x返回x乘x。
Lambda 表达式返回表达式的结果,并采用以下基本形式:
(input parameters) => {statement;}
多个参数时可以使用如下方式
(param1, param2, …paramN) => expr
更为复杂的方式可以如下表示
(param1, param2, …paramN) =>
{
statement1;
statement2;

statementN;
return(lambda_expression_return_type);
}
这里大家需要知道的是“Lambda 表达式”其实就是一个匿名委托,可以使用“Lambda 表达式”的地方必须是可以使用委托的地方,Lambda 运算符 =>左边的是输入参数,Lambda 运算符 =>右边的部分是执行后的输出结果
比如
x => x.Length > 0
相当于
delegate(string x) { return x.Length > 0; }
大家理解了“Lambda 表达式”,我们就可以使用“Lambda 表达式”来完成刚才过滤数据的场景了。代码如下:

 

复制代码
static   void  Main( string [] args)
        {
            
int [] nums  =  {  1 2 3 4 5 6 7 8 9 10  };
            
int [] oddNums  =  Common.FilterArrayOfInts(nums, i  =>  ((i  &   1 ==   1 ));
            
foreach  ( int  i  in  oddNums)
                Console.WriteLine(i);
}
复制代码

 

这段代码比刚才匿名委托的方式易读性要好很多了吧


本文转自 你听海是不是在笑 博客园博客,原文链接:http://www.cnblogs.com/nuaalfm/archive/2008/08/06/1262202.html  ,如需转载请自行联系原作者

相关文章
|
11天前
|
SQL 存储 程序员
SQL查询的一些基本知识和学习指导
【6月更文挑战第17天】SQL查询核心包括基础选择、连接(JOIN)、子查询、聚合函数与GROUP BY、模糊匹配(LIKE)、分页与排序。JOIN操作连接多表,GROUP BY配合聚合函数做统计,LIKE用于模糊搜索。理解存储过程、触发器及自动增长列等进阶概念,通过实践提升SQL技能。
41 2
|
7天前
|
SQL 数据库
零基础学习数据库SQL语句之操作表中数据的DML语句
零基础学习数据库SQL语句之操作表中数据的DML语句
10 0
零基础学习数据库SQL语句之操作表中数据的DML语句
|
11天前
|
SQL 存储 关系型数据库
【数据库】SQL零基础入门学习
【数据库】SQL零基础入门学习
29 3
|
24天前
|
SQL 存储 关系型数据库
sql学习数据库
SQL(Structured Query Language)是用于管理关系型数据库的标准编程语言。学习SQL数据库涉及理解数据库的基本概念、SQL语言的结构和语法,以及如何使用SQL来查询、插入、更新
|
7天前
|
SQL 前端开发 关系型数据库
零基础学习数据库SQL语句之查询表中数据的DQL语句
零基础学习数据库SQL语句之查询表中数据的DQL语句
7 0
|
7天前
|
SQL 关系型数据库 MySQL
零基础学习数据库SQL语句之定义数据库对象的DDL语句
零基础学习数据库SQL语句之定义数据库对象的DDL语句
13 0
|
14天前
|
SQL 关系型数据库 MySQL
MySQL学习必备SQL_DDL_DML_DQL
MySQL学习必备SQL_DDL_DML_DQL
7 0
|
1月前
|
SQL 关系型数据库 MySQL
0基础学习SQL注入之万能账号密码(BUUctf例题-[极客大挑战 2019]EasySQL1)
0基础学习SQL注入之万能账号密码(BUUctf例题-[极客大挑战 2019]EasySQL1)
|
24天前
|
SQL 数据库
sql数据库学习多久
SQL数据库学习的时间长度因个人基础、学习目标和投入时间而异。一般来说,可以分为以下几个阶段: 1. **入门阶段**:如果每天能够投入1\\~2小时的时间去学习并动手练习,通常一周可以达到入门
|
24天前
|
SQL 存储 数据可视化
sql学习数据库
SQL(Structured Query Language)是用于管理关系型数据库的标准编程语言。学习SQL数据库涉及理解数据库的基本概念、SQL语言的组成以及如何使用SQL进行数据的查询、操作和处理