写点什么

VB 和 C#中的 LINQ 聚合

  • 2007-09-18
  • 本文字数:1954 字

    阅读完需:约 6 分钟

Aggregate 是一个可以从一个数据集合中获取标量值的函数,比如 T-SQL 中的 Min()、Max() 和 Sum() 等。现在 VB 和 C#也都对这种聚合的功能给于了支持,但是是以一种非常不同的方式。

VB 和 C#都是以扩展方法的形式支持聚合的。在一个 IEnumberable 对象中,一个简单的调用是通过点符号完成的,比如:

<pre dir="ltr"><p dir="ltr">var totalVirtualMemory = <br></br> (from p in Process.GetProcesses() </p><p dir="ltr"> select p.VirtualMemorySize64).Sum();</p><p>Dim totalVirtualMemory = _</p><br></br> (From p In Process.GetProcesses _<br></br> Select p.VirtualMemorySize64).Sum从这儿可以看到,VB 和 C#的版本几乎是一样的。但 VB 还为聚合专门提供了一个 LINQ 语法:

<pre dir="ltr"><p dir="ltr">Dim totalVirtualMemory = Aggregate p In Process.GetProcesses _ </p><p dir="ltr"> Into p.VirtualMemorySize64</p>如果这是二者之间唯一区别的话,那么也就没有什么好谈的了。但是,有趣的事情发生在当你想同时操作不止一个“列”的时候。简便起见,我们假设要操作正在使用的全部虚拟内存和全部工作集(物理内存)。

使用匿名类,我们可以轻松地创建一个带有它们两个值的变量。

<pre dir="ltr"><p dir="ltr">var totals = new <br></br>{ <br></br> totalVirtualMemory = (from p in Process.GetProcesses() </p><p dir="ltr"> select p.VirtualMemorySize64).Sum(), <br></br> totalWorkingSet = (from p in Process.GetProcesses() </p><p dir="ltr"> select p.WorkingSet64).Sum() <br></br>};</p>这儿的问题是 GetProcesses() 被调用了两次。也就是说操作系统必须查询两次,在结果集合中执行两次循环。一个更快的方法也许是对 GetProcesses() 的调用进行缓存。

<pre dir="ltr"><p dir="ltr">var processes = (from p in Process.GetProcesses() <br></br> select new { p.VirtualMemorySize64, p.WorkingSet64 }</p><p dir="ltr"> ).ToList();</p><p dir="ltr"><br></br>var totals2 = new <br></br>{ <br></br> totalVirtualMemory = (from p in processes <br></br> select p.VirtualMemorySize64).Sum(), <br></br> totalWorkingSet = (from p in processes <br></br> select p.WorkingSet64).Sum() <br></br>};</p>虽然好了一些,但仍然需要两次循环。如何只执行一次呢?这时我们需要一个定制的聚合器,和一个保存这些结果的命名类(Named Class)。

<pre dir="ltr"><p dir="ltr">public static ProcessTotals Sum(this IEnumerable source) <br></br>{ <br></br> var totals = new ProcessTotals(); <br></br> foreach (var p in source){ <br></br> totals.VirtualMemorySize64 += p.VirtualMemorySize64; <br></br> totals.WorkingSet64 += p.WorkingSet64; <br></br> } <br></br> return totals; <br></br>} </p><p>public class ProcessTotals </p><br></br>{ <br></br> public long VirtualMemorySize64 { get; set; } <br></br> public long WorkingSet64 { get; set; } <br></br>} <p>var totals3 = (from p in Process.GetProcesses() select p).Sum();</p>开发者在 Visual Basic 中也可以这样做,但需要像下面这样做:

<pre dir="ltr"><p dir="ltr">Dim totals3 = Aggregate p In Process.GetProcesses _ <br></br> Into virtualMemory = Sum(p.VirtualMemorySize64), _<br></br> workingSet = Sum(p.WorkingSet64)</p>就像在上一个 C#例子中,我们是用一个含有两个 Field 的变量解决问题的。但这和 C#的例子不一样,你不会因为是选择创建自己的聚合函数及类还是在遍历集合中浪费两次循环,而左右为难。

公平起见,C#确实还有那么几招。不像 VB 那样只支持单行的匿名函数,只要需要,C#可以让它们很复杂,这就使得它可以在需要的时候创建匿名的聚合函数。

<pre dir="ltr"><p dir="ltr">var processes = <br></br> (from p in Process.GetProcesses() <br></br> select new { p.VirtualMemorySize64, p.WorkingSet64 }); <br></br>var totals4 = processes.Aggregate(new ProcessTotals(), (sum, p) => <br></br> { <br></br> sum.WorkingSet64 += p.WorkingSet64; <br></br> sum.VirtualMemorySize64 += p.VirtualMemorySize64; <br></br> return sum;</p><p dir="ltr"> });</p>注意在这儿,ProcessTotals 类依然需要用到。匿名类不能被用在这儿,因为 C#匿名类是不可变的。虽然 Visual Basic 的匿名类可以改变,但是在这儿也没用,因为 VB 不能创建多行的匿名函数。

但是 Visual Basic 和 C#都较从前有了强有力的改进,双方也各有长处,让对方在不足之处加油赶上。

查看英文原文: LINQ Aggregates in VB and C#

2007-09-18 04:261343

评论

发布
暂无评论
发现更多内容

疫情下的在线教育行业未来发展

anyRTC开发者

音视频 WebRTC 在线教育 视频直播 双师课堂

数据仓库的基本概念

大数据技术指南

7月日更

了解腾讯京东字节等面试风格,掌握财富钥匙,大厂前端面试稳啦!

前端依依

程序员 面试 大前端 经验分享

熵核科技,自主研发虚拟机赋能安全操作系统

熵核科技

支付安全 安全操作系统 物联网安全 eSIM安全

字节取消“大小周”,管理者与员工的“灵魂争夺战"从未停歇

保洁阿姨分享:腾讯架构师JDK源码笔记,13万字,带你飙向实战

Java架构师迁哥

了不起的开发者 丨 有奖征文活动来啦!

百度开发者中心

百度 开发者 征文

首个SSRF漏洞开篇学习

网络安全学海

网络安全 信息安全 渗透测试 漏洞分析 SSRF

【redis前传】自己手写一个LRU策略

zxhtom

Java redis 原理 造轮子 jdk运用

hadoop 1.0 和 hadoop 2.0 的区别

五分钟学大数据

hadoop 7月日更

fil矿机怎么选择?用什么fil矿机比较好?

FIL矿机怎么买 fil挖矿

物联网安全难题还需行业标杆来解

熵核科技

物联网安全

Ta想做一粒智慧的种子

脑极体

5分钟速读之Rust权威指南(四十一)高级类型

wzx

rust

国内报价-APP时间加速

Qunar技术沙龙

优化逻辑 优化 优化技巧 优化业务 报价

我乃平常客,本持平常心| 2021 年中总结

编程三昧

程序人生 大前端 代码人生

性能测试软启动初探

FunTester

性能测试 接口测试 测试框架 压力测试 测试开发

攒塑料袋,究竟是如何刻进中国人DNA的?

脑极体

没想到我也可以入职阿里!二本毕业、两年crud经验,侥幸通过面试定级P6

Java架构师迁哥

医美行业哪个环节最赚钱?

石云升

行业分析 7月日更

重温历史 致敬百年 “复兴大道100号”线上VR展馆正式开馆

百度大脑

百度 虚拟现实

算法大赛报名 | OMG!这些名企的真实数据竟用来battle

工赋开发者社区

算法 工业互联网

7.24 杭州站 | 阿里云 Serverless Developer Meetup 开放报名!

Serverless Devs

云计算 阿里云 Serverless 云原生

懂了!时间复杂度O(1),O(logn) ,O(n),O(nlogn)...

Ayue、

数据结构

架构实战营1期第二模块作业

五只羊

架构实战营

JVM锁bug导致G1 GC挂起问题分析和解决

毕昇JDK社区

2021世界人工智能大会召开,百度飞桨人工智能产业赋能中心于上海浦东启动运营

百度大脑

人工智能 大数据 百度 物联网

Vue进阶(幺叁捌):vue路由传参的几种基本方式

No Silver Bullet

Vue 路由 7月日更

火爆 GitHub!这个图像分割神器开源了

百度大脑

百度 算法

拥抱云原生,腾讯发布TCSS容器安全服务!

腾讯安全云鼎实验室

容器 云原生

从零开始学习3D可视化之摄像机自由飞行

ThingJS数字孪生引擎

大前端 可视化 3D 数字孪生

VB和C#中的LINQ聚合_.NET_Jonathan Allen_InfoQ精选文章