• vs2008 使用LINQ来简化编程的7个技巧


    http://igoro.com/archive/7-tricks-to-simplify-your-programs-with-linq/

    LINQ体验系列文章导航:http://www.cnblogs.com/lyj/articles/1119671.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 in array1) {
            DoSomething(x);
        }
     
        foreach (var in array2) {
            DoSomething(x);
        }
        这样的话,循环主体会很大,而且他也不希望这样重复的代码。但是,他又不希望创建一个数组来保存array1和array2的所有元素。
        LINQ提供了一种优雅的解决方案:Concat操作。我们可以使用单个循环来重写上面的代码,如下:
        foreach (var 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 in Enumerable.Range(0, 1 << arr.Length)
                      select
                          from 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。这里的每一段代码都可行,但是我不能保证什么,请在使用前仔细检查。

    http://hi.baidu.com/moonnight366/blog/item/a512a5c4659592af8226ac87.html
    几种常用的测试工具:
    http://hi.baidu.com/moonnight366/blog/item/4a6b7aa8c3432bb7cb130cca.html
  • 相关阅读:
    如何编写一个简单的依赖注入容器
    网站框架的动态编译的实现原理
    Python实现语音识别和语音合成
    OpenCV图像处理以及人脸识别
    Shell教程快速入门
    TensorFlow入门教程
    如何免费使用Google的GPU跑深度学习代码
    高等数学系列文章
    Git系列教程
    一键构造你的博客园目录
  • 原文地址:https://www.cnblogs.com/zxhoo/p/2004413.html
Copyright © 2020-2023  润新知