转载地址:http://www.cnblogs.com/lovecherry/archive/2008/05/23/1205565.html

自从学习LINQ以来,我发现了很多使用LINQ来改善代码的方式。每一个技巧都让代码写起来更简单,可读性更强。

这里总结了这些技巧。我会介绍如何使用LINQ来:

  • 初始化数组
  • 在一个循环中遍历多个数组
  • 生成随机序列
  • 生成字符串
  • 转换序列或集合
  • 把值转换为长度为1的序列
  • 遍历序列的所有子集

如果你在LINQ方面有心得也欢迎在评论中一起分享。

1. 初始化数组

通常,我们需要把数组的值初始化为相同的值或递增的序列值,或者可能是一个步进不为1的递增/递减序列。有了LINQ,我们可以在数组的初始化器中完成所有工作,不再需要循环!

在如下的示例代码中,第一行代码初始化了一个长度为10的数组,所有元素都是-1,第二行代码初始化b为0、1、2到9,第三行代码初始化c为100、110、120到190.

int[] a = Enumerable.Repeat(-1, 10).ToArray();

int[] b = Enumerable.Range(0, 10).ToArray();

int[] c = Enumerable.Range(0, 10).Select(i => 100 + 10 * i).ToArray();

要提醒一下:如果你初始化一个很大的数组,最好不考虑这种优雅的方式而是使用传统的方式来替代。LINQ的这种解决方案会动态产生数组,因此垃圾数组需要在运行时被回收。也就是说,我总是会在小数组或测试调试代码的情况下使用这种技巧。

2. 在一个循环中遍历多个数组

有个朋友问我一个C#的问题:有没有办法在一个循环中遍历多个集合?他的代码差不多是这样:

foreach (var x in array1) {

DoSomething(x);

}

foreach (var x in array2) {

DoSomething(x);

}

这样的话,循环主体会很大,而且他也不希望这样重复的代码。但是,他又不希望创建一个数组来保存array1和array2的所有元素。

LINQ提供了一种优雅的解决方案:Concat操作。我们可以使用单个循环来重写上面的代码,如下:

foreach (var x in array1.Concat(array2)) {

DoSomething(x);

}

注意,由于LINQ在枚举器级别进行操作,他不会产生新的数组来保存array1和array2的元素。因此,除了优雅之外,这个方案还很高效。

3. 生成随机序列

这是一个生成N长度随机序列的简单技巧:

Random rand = new Random();

var randomSeq = Enumerable.Repeat(0, N).Select(i => rand.Next());

有了LINQ的延迟特性,序列不会实现进行计算并保存到数组中,而是在迭代randomSeq的时候按需生成随机数。

4. 生成字符串

LINQ同样也是生成各种类型字符串的好工具。对于测试或调试,生成字符串时很有用的。假设我们需要生成一个N长度的字符串,按照“ABCABCABC”的方式。使用LINQ,解决方案非常优雅:

string str = new string(

Enumerable.Range(0, N)

.Select(i => (char)(‘A’ + i % 3))

.ToArray());

    Petar Petrov给出了另外一种有趣的方式使用LINQ来生成字符串:

string values = string.Join(string.Empty, Enumerable.Repeat(pattern, N).ToArray());

5. 转换序列或集合

在C#或VB中我们不能实现把序列从T类型转换为U类型,即使T从U类继承。因此,即使把List<string>转换为List<object>也很难实现。(要解释为什么,请看Bick Byer的帖子)。但是如果要把IEnumerable<T>转换为IEnumerable<U>的话,LINQ有一个简单而有效的解决方案:

IEnumerable<string> strEnumerable = …;

IEnumerable<object> objEnumerable = strEnumerable.Cast<object>();

如果我们需要转换List<T>为List<U>,LINQ也提供了解决方案,但是它会进行列表的复制:

List<string> strList = …;

List<object> objList = new List<object>(strList.Cast<object>());

    Chris Cavanagh建议另外一种解决方式:

var objList = strList.Cast<object>().ToList();

6. 把值转换为长度为1的序列

当我们需要把单个值转化为一个长度为1的序列时,会怎么做?我们可以创建一个长度为1的数组,但是我还是喜欢LINQ的Repeat操作:

IEnumerable<int> seq = Enumerable.Repeat(myValue, 1);

7. 遍历序列的所有子集

有的时候,遍历数组的所有子集很有用。子集和问题布尔可满足性问题以及背包问题都可以通过遍历某个序列的所有子集来简单解决。

有了LINQ,我们可以如下声场所有arr数组的子集:

T[] arr = ...;

var subsets = from m in Enumerable.Range(0, 1 << arr.Length)

select

from i in Enumerable.Range(0, arr.Length)

where (m & (1 << i)) != 0

select arr[i];

注意,如果子集的个数超过了int,上面的代码就不能工作。因此,仅当你知道arr的长度不超过30的时候才去使用这个方式。如果arr长度超过30,你应该不会是想去遍历所有的子集,因为可能这会耗费几分钟或更长的时间。

评论和总结

希望这些技巧对你有用,这些示例代码都使用C#实现,但是你可以很容易得改变为其它.NET语言。然而,LINQ对于支持扩展方法、lambda表达式和类型推断的语言更方便,比如C#和VB。这里的每一段代码都可行,但是我不能保证什么,请在使用前仔细检查。

使用LINQ来简化编程的7个技巧的更多相关文章

  1. LINQ to XML 编程基础

    1.LINQ to XML类 以下的代码演示了如何使用LINQ to XML来快速创建一个xml: 隐藏行号 复制代码 ?创建 XML public static void CreateDocumen ...

  2. EF(Linq)框架使用过程中的小技巧汇总

    这篇博客总结本人在实际项目中遇到的一些关于EF或者Linq的问题,作为以后复习的笔记或者供后来人参考(遇到问题便更新). 目录 技巧1: DbFunctions.TruncateTime()的使用 技 ...

  3. EF(Linq)框架使用过程中的小技巧汇总 dbfunctions

    这篇博客总结本人在实际项目中遇到的一些关于EF或者Linq的问题,作为以后复习的笔记或者供后来人参考(遇到问题便更新). 目录 技巧1: DbFunctions.TruncateTime()的使用 技 ...

  4. LINQ to XML编程之编程基础

    1.声明,LINQ to XML让xml的创建变得非常简单. XDocument myDocument = new XDocument( new XDeclaration("1.0" ...

  5. jQuery 插件编程精讲与技巧

    适应的读者: 1.有一定的jquery编程基础但是想在技能上有所提升的人 2.前端开发的程序员 3.对编程感兴趣的学生 为什么要学习jquery插件的编写? 为什么要学习jquery插件的编写?相信这 ...

  6. Python高效编程的19个技巧

    初识Python语言,觉得python满足了我上学时候对编程语言的所有要求.python语言的高效编程技巧让我们这些大学曾经苦逼学了四年c或者c++的人,兴奋的不行不行的,终于解脱了.高级语言,如果做 ...

  7. java基础:eclipse编程不得不知道的技巧

    如果你是位具有开发经丰富的工程师,在开发的过程中,你就会很强烈的要求快捷的编程.如何快捷编程,只有更加熟悉开发工具.那么eclipse是同样也有很多技巧.可以带着下面问题来阅读1.如何查找类相关信息? ...

  8. 关于php编程的一些小技巧

    1. NULL,0和空的区分判断 (1)0与空的区分 <?php  $a = 0;if($a==''){ echo '此判断条件不能区分';}else{ echo '此判断条件可以区分';} ? ...

  9. Shell 编程基础之注意技巧

    退出状态bash中的内建命令虽然不创建新的进程,但也会有Exit Status,通常也用0表示成功非零表示失败,可以用特殊变量$?读出 命令代换:`或$() user@ae01:~$ echo `da ...

随机推荐

  1. C语言运算符学习笔记

    运算符不仅具有不同的优先级,还有不同的结合性.在表达式中,各运算量参与运算的先后顺序不仅要遵守运算符优先级别的规定,还要受运算符结合性的制约,以便确定是自左向右进行运算还是自右向左进行运算. C语言的 ...

  2. 【转】Objective-C 与 Runtime:为什么是这样?

    原文地址: http://t.cn/RyyNIXd?u=2483713130&m=3884400301576073&cu=2483713130 笔者非常高兴能为Objective-C写 ...

  3. C# System.Object基类

    System.Object 基类 System.Object在.Net中是所有类型的基类,任何类型都直接或间接地继承自System.Object.没有指定基类的类型都默认继承于System.Objec ...

  4. Oracle 10g体系机构及安全管理《思维导图》

    通过学习Oracle数据库后,我对数据库又有了进一步的了解,Oracle数据库 10g体系机构分为 物理和逻辑存储结构. 下面是我对Oracle数据库做的思维导图和笔记 (全屏查看:<思维导图& ...

  5. jdk8预览

    原文:http://www.techempower.com/blog/2013/03/26/everything-about-java-8/ 1.接口增强 (1)接口可以定义static方法 java ...

  6. MFC DestroyWindow窗口对象和窗口句柄的销毁

    考虑单窗口情况: 假设自己通过new创建了一个窗口对象pWnd,然后pWnd->Create.则销毁窗口的调用次序: 1. 手工调用pWnd->DestroyWindow(): 2. De ...

  7. svn小技巧——重定向svn diff

    svn diff的默认输出模式比较冗长,如果遇到修改比较多的情况,有时会较难看清diff.svn本身提供了自定义diff输出的选项,可能的修改方法如下: 建立一个脚本文件(如svndiff.sh),调 ...

  8. 百度地图LV1.5实践项目开发工具类bmap.util.jsV1.0

    /** * 百度地图使用工具类-v1.5 * * @author boonya * @date 2013-7-7 * @address Chengdu,Sichuan,China * @email b ...

  9. [转]ActiveMQ 即时通讯服务 浅析

    一. 概述与介绍 ActiveMQ 是Apache出品,最流行的.功能强大的即时通讯和集成模式的开源服务器.ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provide ...

  10. java中return和continue区别

    编程语言大多是想通的,当然java也不例外,下面的在其他编程语言也是相同的道理. return与continue的区别 先看代码哦 class demo2 { public static void m ...