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 };//错误

 

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

 

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  ,如需转载请自行联系原作者

相关文章
|
4天前
|
Java 物联网 C#
C#/.NET/.NET Core学习路线集合,学习不迷路!
C#/.NET/.NET Core学习路线集合,学习不迷路!
|
1月前
|
SQL 存储 数据库
SQL学习一:ACID四个特性,CURD基本操作,常用关键字,常用聚合函数,五个约束,综合题
这篇文章是关于SQL基础知识的全面介绍,包括ACID特性、CURD操作、常用关键字、聚合函数、约束以及索引的创建和使用,并通过综合题目来巩固学习。
32 1
|
1月前
|
开发框架 缓存 算法
开源且实用的C#/.NET编程技巧练习宝库(学习,工作,实践干货)
开源且实用的C#/.NET编程技巧练习宝库(学习,工作,实践干货)
|
2月前
|
开发框架 自然语言处理 .NET
C#一分钟浅谈:LINQ 查询表达式的使用技巧
【9月更文挑战第6天】LINQ(Language Integrated Query)是C#开发中的强大工具,使查询数据集合变得简单且接近自然语言。本文从基础入手,通过具体示例讲解LINQ查询表达式的使用技巧,包括过滤、排序和分组等操作。同时,文章还探讨了常见问题及解决方法,如性能优化、过早枚举和类型转换等,帮助开发者写出更高效、易维护的代码。
94 15
|
2月前
|
Linux C# 开发者
Uno Platform 驱动的跨平台应用开发:从零开始的全方位资源指南与定制化学习路径规划,助您轻松上手并精通 C# 与 XAML 编程技巧,打造高效多端一致用户体验的移动与桌面应用程序
【9月更文挑战第8天】Uno Platform 的社区资源与学习路径推荐旨在为初学者和开发者提供全面指南,涵盖官方文档、GitHub 仓库及社区支持,助您掌握使用 C# 和 XAML 创建跨平台原生 UI 的技能。从官网入门教程到进阶技巧,再到活跃社区如 Discord,本指南带领您逐步深入了解 Uno Platform,并提供实用示例代码,帮助您在 Windows、iOS、Android、macOS、Linux 和 WebAssembly 等平台上高效开发。建议先熟悉 C# 和 XAML 基础,然后实践官方教程,研究 GitHub 示例项目,并积极参与社区讨论,不断提升技能。
88 2
|
3月前
|
SQL 存储 关系型数据库
PostgreSQL核心之SQL基础学习
PostgreSQL核心之SQL基础学习
43 3
|
3月前
|
开发框架 .NET API
C#/.NET/.NET Core推荐学习书籍(24年8月更新)
C#/.NET/.NET Core推荐学习书籍(24年8月更新)
|
5月前
|
SQL 存储 Java
SQL数据库学习指南:从基础到高级
SQL数据库学习指南:从基础到高级
|
4月前
|
SQL 存储 关系型数据库
关系型数据库SQL Server学习
【7月更文挑战第4天】
76 2
|
4月前
|
Dart 算法 JavaScript
C#数据结构与算法入门教程,值得收藏学习!
C#数据结构与算法入门教程,值得收藏学习!