写点什么

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

评论

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

NTFS Disk by Omi NTFS for Mac(NTFS 磁盘管理器) v1.1.4激活版

iMac小白

What’s the future ofIPQ9574 with QCN9274 Solution in Industrial Communication?

wallyslilly

文心千帆:从PPT制作到数字人主播,ERNIE-Bot|BLOOMZ大模型调优与RLHF训练全攻略

百度开发者中心

大模型 千帆

人大金仓助力吉林省属国企核心财务系统批量上线

科技热闻

高效运维|AIRIOT智慧电力运维解决方案

AIRIOT

数据分析 物联网平台 电力 智慧电力 智能控制

软件测试学习笔记丨软件测试基础概念

测试人

软件测试

Linux服务器部署Web版VSCode,在window下使用浏览器在linux环境下编写代码

快乐非自愿限量之名

Linux 运维 服务器

云原生最佳实践系列 5:基于函数计算 FC 实现阿里云 Kafka 消息内容控制 MongoDB DML 操作

阿里巴巴云原生

kafka 阿里云 云原生

MCtalk·CEO对话×e签宝丨如何修好SaaS生态建设这门CEO必修课?

ToB行业头条

听完这期音视频发展史,才更清楚元宇宙到底还行不行|编码人声

声网

对话 Mines of Dalarnia: Web3 游戏创新,社区驱动与公链共建

Footprint Analytics

gamefi #Web3

TikTok直播专线的优势

Ogcloud

海外直播专线 tiktok直播 tiktok直播专线 海外直播网络 tiktok直播网络

SD-WAN如何适应运营商网络

Ogcloud

SD-WAN 企业组网 SD-WAN组网 SD-WAN服务商 SDWAN

如何构建一台机器学习服务器

EquatorCoco

机器学习 数据库 服务器

提高LED显示屏安全性的关键措施

Dylan

安全 事故 消费者 LED显示屏 led显示屏厂家

Abaqus模拟新能源汽车电池理论概念

思茂信息

abaqus abaqus软件 abaqus有限元仿真

ETLCloud结合Oracle实现CDC

RestCloud

oracle 数据同步 ETL CDC

Lightroom Classic 2022 for Mac(LrC中文版) 11.5激活版

iMac小白

10大开源文档管理系统

爱吃小舅的鱼

开源 文档管理 文档管理工具

GraphPad Prism 10 for Mac(统计分析绘图软件) v10.1.1注册版

iMac小白

黑盒Prompt优化:提升大模型反馈效果的新思路

百度开发者中心

大模型 Prompt

RowHammer 攻击:内存的隐形威胁

EquatorCoco

攻击 RAM

华为云&华为终端云创新峰会:华为阅读再迎三个内容伙伴,携手繁荣阅读行业生态

最新动态

玩转云端|演唱会一票难求?快用天翼云边缘安全加速平台AccessOne!

天翼云开发者社区

云计算 安全

TikTok直播专线:解决海外直播稳定问题的关键

Ogcloud

海外直播专线 tiktok直播 tiktok直播专线 海外直播网络 tiktok直播网络

CAE科普!电池仿真的必要性

智造软件

CAE CAE软件 有限元技术

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