【AICon】探索八个行业创新案例,教你在教育、金融、医疗、法律等领域实践大模型技术! >>> 了解详情
写点什么

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:261070

评论

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

产研指南针的量化指标实践笔记

车江毅

项目管理 研发管理 降本增效 北极星指标 效能度量

职场IT老手教你3步教你玩转可视化大屏设计,让领导眼前一亮!

葡萄城技术团队

《解构领域驱动设计》-领域驱动设计统一过程

珑彧

Java 读书笔记 架构 方法论 领域驱动设计

3D可视化:18个WebGL框架和Web3D图形库

2D3D前端可视化开发

WebGL 三维可视化 web3d 3d绘图引擎

压力测试、并发测试实践,后端工程师必看

爱研究代码的极客人

Jmeter 压力测试 并发测试 测试工具

快速入门API Explorer

华为云开发者联盟

云计算 华为云 API Explorer平台 企业号 2 月 PK 榜 华为云开发者联盟

开心档之boostrap按钮组

雪奈椰子

bootstrap 开心档

共铸国云智领未来| 数据进超市,海岛更善治

天翼云开发者社区

“云”上书店,氛围感拉满!

天翼云开发者社区

Knative Autoscaler 自定义弹性伸缩

天翼云开发者社区

一文详解数GaussDB(DWS)函数出参带出方式

华为云开发者联盟

数据库 后端 华为云 企业号 2 月 PK 榜 华为云开发者联盟

Java程序员:为了跳槽刷完1000道真题,想不到老板直接给我升职了

程序知音

Java java面试 Java面试题 Java面试八股文 后端面试

3Dmax和C4d有什么区别?

Finovy Cloud

3DMAX

DAAM:首次利用视觉语言学解释大型扩散模型

Zilliz

开心档之bootstrap卡片

雪奈椰子

bootstrap 开心档

开心档之boostrap轮播

雪奈椰子

bootstrap 开心档

天翼云第八代云主机助力企业攻克上云“大象流”加密处理业务难题

天翼云开发者社区

舞台LED显示屏对灯光设计产生了哪些影响

Dylan

LED显示屏 全彩LED显示屏 led显示屏厂家

iOS AppStore上架流程图文详解2021版 (上)

雪奈椰子

ios apple 上架 apps

开心档之bootstrap折叠

雪奈椰子

bootstrap

找 ChatGPT 写 SQL? 不如试试 PromQL,三行解决复杂时序场景查询

Greptime 格睿科技

sql 云原生 时序数据库 PromQL 可观测

为什么选择免费文件共享方法上的托管文件传输

镭速

腾讯架构师极力推荐:Java多线程与Socket实战微服务框架

小小怪下士

Java 程序员 socket 多线程

如何在 Web 端实现一个多人数独游戏

声网

Vue 互动白板 RTE

一步一腳印的 iOS App 上架和更新流程

雪奈椰子

ios apple 上架 apps

2023年互联网大厂泄露的这1300多道JAVA面试题,包含了程序员的所有技术点

架构师之道

Java 程序员 java面试

Fastjson踩“坑”记录和“深度”学习

阿里技术

Fastjson

开心档之boostrap按钮2

雪奈椰子

bootstrap 开心档

领导者!天翼云蝉联政务公有云基础设施市场第一

天翼云开发者社区

如何将物理机Windows系统迁移到VMware虚拟机?

天翼云开发者社区

《福布斯》评英特尔最新财报:业绩之外,制程路线图的稳步推进是真正的好消息

科技之家

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