Visual Basic 15语言新特性

对于C#的两个重要特性元组和Ref返回值,Visual Basic 15提供了对等的实现。这两个特性都是“不完全的”,但已经可以提供足够的变通方案,让VB应用程序可以消费使用了这些特性的C#库。

元组

在VB中,从单个函数调用直接返回多个值是一个人们期待已久的特性。虽然开发人员可以使用ByRef参数获得同样的结果,但与函数式编程语言相比,其语法相当笨拙。

你可能不熟悉这个术语,“元组”就是一组相关的值。从.NET 4.0开始,Visual Basic就提供了一个标准的Tuple类,但用户体验不那么令人满意。开发人员必须手动解包来获得Tuple的值,而且要使用Item1、Item2等不能提供什么帮助的属性名。

七年之后,VB 15终于为元组提供了语法支持。更确切地说,与堆分配Tuple对象相比,ValueTuple结构提供了更好的性能。下面是一个例子,TryParse方法是使用新的风格编写的:

Public Function TryParse(s As String) As (Boolean, Integer)TryDim numericValue = Integer.Parse(s)Return (True, numericValue)CatchReturn (False, Nothing)End TryEnd Function
Dim result = TryParse(s)If result.Item1 ThenWriteLine(result.Item2)End If

在这个例子中,TryParse的返回值是ValueTuple。这使得函数更简洁了一些,因为你不必再显式说明ValueTuple类型。但是,如你所见,调用它的代码没有任何不同。因此,让我们稍微改进一下,但保持返回类型的字段不变:

Public Function TryParse(s As String) As (IsInteger As Boolean, Value As Integer)…End FunctionDim result = TryParse(s)If result.IsInteger ThenWriteLine(result.Value)End If

你可以使用下面的语法创建带有命名字段的元组:

Dim kvPair = (Key := 5, Value := "Five")

遗憾的是,VB没有提供一种可以将元组“解包”到多个变量的方法。因此,将下面这行C#代码翻译成VB时,每个变量需要一行:

var (key, value) = kvPair;

(By)Ref返回值

Ref返回值,也就是VB中的ByRef返回值,有严格的限制。你可以消费将一个引用(即托管指针)返回给一个字段或数组索引的C#函数,但你无法自己创建,你也无法创建局部ByRef变量。

你所能做的是采用一个相当复杂的变通方法。虽然你无法创建局部ByRef变量,但你可以创建ByRef参数。考虑下下面的C#函数和它在VB中的等价实现:

public ref string FindNext(string startWithString, ref bool found)ByRef Function FindNext(startWithString as string, ByRef found as Boolean) As String

要使用这个函数,Klaus Löffelmann告诉我们,我们需要一个辅助函数:

Private Function VbByRefHelper(Of t)(ByRef byRefValue As t,byRefSetter As Func(Of t, t))
As tDim orgValue = byRefValuebyRefValue = byRefSetter(byRefValue)Return orgValueEnd Function

接下来,你可以将返回ref的函数的结果作为参数传递给辅助函数,同时,你希望将其作为一个单独的匿名函数。

Dim didFind As Boolean'版本#2: 借助一个简单的泛型辅助类:aSentence = New NewInCS2017.Sentence("Adrian is going to marry Adriana,
because Adrian loves Adriana.")DoVbByRefHelper(aSentence.FindNext("Adr", didFind),Function(stringFound) As StringIf stringFound = "Adrian" ThenstringFound = "Klaus"Return stringFoundEnd IfReturn stringFoundEnd Function)Loop While didfind

以下是VB完全实现Ref返回值后的样子,仅供参考:

'THIS DOES NOT WORK IN VB!!!Dim aSentence = New Sentence("Adrian is going to marry Adriana, 
because Adrian loves Adriana.")Dim found = FalseDo' !!In C# we can declare a local variable as ref - in VB we cannot.!!'   This variable could take the result...Dim ByRef foundString = aSentence.FindNext("Adr", found)If foundString = "Adrian" Then' but via the reference, so writing would be possible as well,' and we had a neat find and replace!foundString = "Klaus"End IfLoop While found

那么,VB为什么没有实现ref局部变量呢?

从根本上说是因为还没有东西使用它们。在.NET API中,目前没有任何东西需要使用它们,这个特性最终可能还是会走进死胡同。这以前发生过;几乎没有人使用不安全块,即使在使用原生C程序库时。栈分配数组的情况也一样。

Anthony Green写道:

坦白说,VB2017提供消费ref-returning函数的功能是为了对冲未来的不确定性,而不是为了让那个特性成为主流(即使在C#中也是如此)。

[…]

如果你看一下C#的这个版本,该特性带来了另一个特性,即ref局部变量。关于ref局部变量,也有一些考虑,ref再赋值(将一个局部变量“指向”另一个位置)以及ref局部变量默认只读,如何在所有可以引入变量的地方指定ref,区分普通赋值和ref赋值,类似这样的决策都需要在VB中解决,以便获得同样的生产能力。有大量的工作要做。

在VB中,工作量会更大,因为VB有额外的功能使用了ByRef,比如传递ByRef属性。VB编译器开发负责人Jared Parsons有一篇不错的博文,列举了许多在VB中使用ByRef的案例,可以说明这一点。返回一个ByRef属性,并在一个后期绑定的上下文中处理ByRef真得没有任何意义,因此, 与令人费解的ByRef参数相比,该语言对ByRef返回值的处理方式有所不同(而Jared现在得将更多的案例补充到那篇博文了)。那会给VB带来大量的困惑、语法和概念负担,因为C#增加了一项某一天可能用于编写一个集合类型的特性。

相反,我们采用一种不同的方法。简而言之,我们仅仅实现消费场景所需的特性,让你使用Slice(或者类似的返回ref的东西)就刚好可以完成你可以对数组进行的操作,除此之外,不提供任何额外的特性。当你使用索引指定一个数组元素时,你可以直接给它赋值,但你不能将数组元素的引用赋值给ref局部变量,并稍后再赋值给数组,你可以在那个索引指定的位置对值进行修改,你可以传递那个ByRef元素,但不能返回ByRef。也就是说,没有新语法,VB得到了保护。如果在VS2017发布之后,该语言的下一个版本发布之前,我们增加了Slice,而它作为一个集合类型,成了所有集合类型的终结者,一夜之间出现了数百万计的API返回ByRef类型。如果这个可能性微乎其微的噩梦永远不会发生,那么该语言就不会受此损害。这就是为什么它要那样设计。

(感兴趣的读者可以通过上面的链接阅读完整解释)

VB不是唯一一门这样做的语言。同样的考虑使得C#没有包含对XML库的支持,许多ASP.NET MVC开发人员都会希望它有这个特性。

原文地址:http://www.infoq.com/cn/news/2017/04/VB-15


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/325952.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Struts2面试问题

转载自 Struts2面试问题 1.什么是Struts2? Apache Struts2是一个用Java构建Web应用程序的开源框架。Struts2基于OpenSymphony WebWork框架。它从Struts1中得到了很大的改进,使其更加灵活,易于使用和扩展。Struts2的核心组件是Action&…

谷歌工程师文化中的几个核心原则

转载自 谷歌工程师文化中的几个核心原则 每周,一组谷歌员工都会在厕所的墙壁上粘贴一页来分享本周的测试小建议。有时这页纸会讨论依赖注入,并提供一个简单的示例展示如何用不同语言使用它;有时它可能会分享如何安装一个用于测量团队代码库…

初探CSRF在ASP.NET Core中的处理方式

前言 前几天,有个朋友问我关于AntiForgeryToken问题,由于对这一块的理解也并不深入,所以就去研究了一番,梳理了一下。 在梳理之前,还需要简单了解一下背景知识。 AntiForgeryToken 可以说是处理/预防CSRF的一种处理…

HBase体系架构说明

HBase体系架构说明! client:两种—-Hbase shell 命令行接口 JavaAPI client访问Region不能直接访问,首先client需要先连接到zookeeper,zookeeper管理HMaster,说明,hdfs集群,在没有zookeepe…

asp.net core 编译mvc,routing,security源代码进行本地调试

因为各种原因,需要查看asp.net core mvc的源代码来理解运行机制等等,虽说源代码查看已经能很好的理解了。但是能够直接调试还是最直观的。所有就有了本次尝试。因调试设置源代码调试太辍笔,所以不用这个方法,转而使用编译源代码的…

并查集判断是否有环存在

题目描述 思路分析 代码实现 package com.atguigu.disjointSet;public class djset {public static int VERTICES6;public static void initialise(int parent[]){int i;for (i 0; i < VERTICES; i) {parent[i]-1;}}public static int find_root(int x,int parent[]){int …

Visual Studio 2017更新,侧重于提高稳定性

Microsoft已对其旗舰开发软件产品Visual Studio 2017&#xff08;VS2017&#xff09;的安装程序和设置引擎做了全新设计&#xff0c;意在能快速地部署更新到VS2017。VS2017的第一个命名版本更新在VS2017首发的一个月后就可用&#xff0c;这充分体现了这一全新设计的优势所在。 …

阅读器关闭时尝试调用Read无效时的解决方法

今天在写asp .netmvc的项目时&#xff0c;发现了个困扰我很久的问题&#xff0c;经过仔细研究终于解决了。 问题如下&#xff1a; 首先来看一下原来有问题的代码&#xff1a; public static SqlDataReader Excutereader(string sql,params SqlParameter [] param) {using (SqlC…

.NET或将引入类型类和扩展

类型类是另外一项正被考虑引入.NET未来版本的特性。在提案“外观和扩展&#xff08;Shapes and Extensions&#xff09;”中&#xff0c;该特性被称为外观&#xff0c;它们将大幅提升.NET泛型的能力。Mads Torgersen这样描述类型类&#xff1a; 接口抽象的是作为类型实例的对象…

成为更优秀的程序员:退后一步看问题

转载自 成为更优秀的程序员&#xff1a;退后一步看问题 一天&#xff0c;在工作中… Bug #3890 来自客户&#xff1a; 有个程序出现了错误&#xff0c;程序提示说“SpeedCalculator::compute()里出现了除零情况”。 请尽快修复&#xff01; 你打开SpeedCalculator.php&#…

深夜福利, 小试linuxkit

前言 今天小编的朋友圈被DockerCon和linuxkit刷屏了&#xff0c;再不出来写点linuxkit的东东恐怕就要跟不上时代了。小编翻阅了N多的有关linuxkit的文章&#xff0c;发现绝大多数都是英文的讲解&#xff0c;小编本着对读者负责的态度决定先将linuxkit的文章翻译成中文&#xff…

.NET Core 2.0及.NET Standard 2.0

.NET Core 2.0的发布时间&#xff0c;.NET Core 2.0预览版及.NET Standard 2.0 Preview大概在5月中旬或下旬发布。 .NET Core 2.0正式版本发布时间大约在Q3 2017发布&#xff0c;具体我估计大概在8月份左右。同时一起发布的也就是.NET Standard 2.0。 MilestoneRelease Date.…

Linux清理磁盘挂载点方法(亲测有效)

问题现象 Linux操作系统云服务器根目录空间占用率过高。例如&#xff0c;以图1为例&#xff0c;根目录空间占用率为96%。 根目录空间占用率过高 查询当前系统存在一个约42G 大小的文件access_log&#xff0c;这个文件应该是apache产生的访问日志文件&#xff0c;从日志大小来…

.NET程序在Linux容器中的演变

本文将首先讨论镜像的构建时间和启动时间&#xff0c;接着会将一个简单的.NET程序运行在基于容器的应用上&#xff0c;然后观察镜像大小的变化&#xff0c;最终缩短镜像的构建和加载时间。此外&#xff0c;代码优化是本文的另一个主题。 现在&#xff0c;.NET开发人员可以无障…

微服务的概念——《微服务设计》读书笔记

《领域驱动设计》&#xff08;Eric Evans&#xff09;&#xff1a;告诉我们用代码呈现真实世界的重要性&#xff0c;并且告诉我们如何更好地建模。 持续交付理论&#xff1a;如何更有效及更高效地发布软件品&#xff0c;并指出保持每次提交均可发布的重要性。 六边形架构理论&a…

想要玩转实现负载均衡,你知道这些吗?

转载自 想要玩转实现负载均衡&#xff0c;你知道这些吗&#xff1f; 一、前言 互联网早期&#xff0c;业务流量比较小并且业务逻辑比较简单&#xff0c;单台服务器便可以满足基本的需求&#xff1b;但随着互联网的发展&#xff0c;业务流量越来越大并且业务逻辑也越来越复杂&…

netcore实践:跨平台动态加载native组件

缘起netcore框架下实现基于zmq的应用。在.net framework时代&#xff0c;我们进行zmq开发由很多的选择&#xff0c;比较常用的有clrzmq4和NetMQ。 其中clrzmq是基于libzmq的Interop包装&#xff0c; NetMQ是100%C#的zmq实现&#xff08;基于AsyncIO组件&#xff09;。以上两种…

如何实现酷狗音乐pc页面点击播放时,打开多个歌曲播放时,始终在一个播放页面,(标签页的通讯)

大致有两种思路&#xff0c; 一种是通过wind.open()方法传第二个参数&#xff0c; A页面&#xff1a; //点击跳转播放页函数function toPlayPage(){window.open(path/xxxx/xxxx?name音乐名,music)//第二个参数写一个定值&#xff0c;代表跳转页面都为music标签页&#xff0…

Redis进阶之内存模型

转载自 Redis进阶之内存模型 前言 Redis是目前最火爆的内存数据库之一&#xff0c;通过在内存中读写数据&#xff0c;大大提高了读写速度&#xff0c;可以说Redis是实现网站高并发不可或缺的一部分。 我们使用Redis时&#xff0c;会接触Redis的5种对象类型&#xff08;字符…