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

类型类是另外一项正被考虑引入.NET未来版本的特性。在提案“外观和扩展(Shapes and Extensions)”中,该特性被称为外观,它们将大幅提升.NET泛型的能力。Mads Torgersen这样描述类型类:

接口抽象的是作为类型实例的对象和值的“外观(shape)”。从根本上讲,类型类背后的思想是抽象类型本身的外观。而且,当通过类型声明引入需要的类型实现一个接口时,其他人可以在单独的代码中实现类型类。

类型类解决了一个长期存在的接口问题:它们无法处理静态函数或操作符重载。这导致了一些问题,比如,在数学库中,对于不同的数值数据类型,需要反复声明相同的函数。

Mads总结道:

一般来说,外观的声明和接口声明非常像,但它:

几乎可以定义任意类型的成员(包括静态成员)

可以通过扩展实现

可以在特定的地方像类型一样使用

最后一个限制很重要:外观不是类型。外观的主要目的是作为泛型的一种约束,限定类型参数,保证它们有正确的外观,并允许泛型声明体使用那个外观。

与外观的思想紧密相关的是一种经过改进的扩展语法。扩展结构几乎可以为类型类提供任何东西,而不只是方法扩展。考虑下面这个最简单的例子:

public shape SNumber<T>
{static T operator +(T t1, T t2);static T operator -(T t1, T t2);static T Zero { get; }
}

Int32类型已经提供了大部分内容,但它缺少zero属性。扩展可以修复这个问题:

public extension IntGroup of int : SNumber<int>
{public static int Zero => 0;
}

然后,你可以像下面这样使用它:

public static AddAll<T>(T[] ts) where T : SNumber<T> // shape用作约束
{var result = T.Zero; // 使用shape的Zero属性foreach (var t in ts) { result += t; } //使用shape的+ 操作符return result;
}

实现

这实现起来需要一些接口和结构方面的技巧。

  • Shapes被翻译成了接口,每个成员(甚至是静态成员)都转换成了接口中的实例成员;

  • 扩展被翻译成了结构,每个成员(甚至是静态成员)转换成了结构中的实例成员;

  • 如果扩展实现了一个或多个弯管,则底层的结构实现了那些外观的底层接口。

通常,上述结构被称为“见证结构(witness struct)”。它的存在可以证明一个类遵循外观的规则。或者换句话说,该类在类型类中。

编译器会将上述AddAll方法翻译成如下代码:

public static T AddAll<T, Impl>(T[] ts) where Impl : struct, SNumber<T>
{var impl = new Impl();var result = impl.Zero;foreach (var t in ts) { result = impl.op_Addition(result, t); }return result;
}

然后,上述见证结构就可以用于向AddAll方法提供必要的功能。结构可以直接在类型上调用方法或者根据需要使用扩展结构。

在类和接口中实现外观

使用和我们扩展基类及实现接口一样的语法,类可以显式实现一个外观。然后,编译器会提供相应的见证结构。

也可以将接口标记为满足外观的要求。下面是一个例子:

public extension Comparable<T> of IComparable<T> : SComparable<T> ;

由于IComparable和理论上的类型类之间存在一对一关系,所以我们不需要为扩展结构提供扩展体。

泛型类型

事实证明,泛型类型有他们自己的问题。和泛型方法一样,向泛型类添加外观或者类型类作为类型约束需要额外提供一个类型参数。在泛型类上,由于类型参数的数量是其名称的一部分,所以这会导致它和其它名称相同的泛型类型发生冲突。

扩展外观

扩展结构不仅可以用于实现外观,还可以扩展它们。因此,你可以向现有的外观中添加新方法、静态方法及操作符。正如扩展方法一样,语法是一样的,就像它们在底层类型上直接定义了一样。

评论

总的来说,人们对于该特性的反应不错。不过,也有一些修改请求。例如,外观目前必须显式实现。有些开发人员希望,如果特定的类或接口不需要额外扩展方法时,就由编译器隐式实现。Mads列举了这样做的一些问题:

那可能会导致,为了见证以相同的方式应用到同一类型的同一个外观而生成许多结构类型,有生成的类型过度扩散的风险。如果编译器比较聪明,每个程序集只生成一个,或许可以缓解这种情况,但我们从匿名类型了解到,这种重复数据删除技术非常困难,而且很容易出错。

如果我们允许泛型类型拥有外观约束的类型参数,那么同一个东西拥有多个见证结构会导致实例化的泛型类型具有不同的类型标识,无法互换。

人们还担心外观和扩展绑定得太紧。他们认为,那将来可能会引起混淆。

对此,Mads答复说:

合并:在我的提案里,“扩展”实际上合并了多个问题:

[……]

我觉得,对于上述服务于所有这些目的的语言机制,有太多内容需要讨论——但归根结底,它们的关系非常密切。如果有一个提案可以将它们清晰地分开,那将是非常有意义的。那也许会更加简单有效。

原文地址:http://www.infoq.com/cn/news/2017/04/DotNet-Type-Classes


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

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

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

相关文章

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

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

JAVA生成随机数

方式一 Random rand new Random();for(int i0; i<10; i) {System.out.println(rand.nextInt(10) 1);}方式二 for (int i 0; i < 50; i) {arr[i](int)(100*Math.random());}

深夜福利, 小试linuxkit

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

HBase的hbase shell 详解

进入hbase命令行 ./hbase shell 显示hbase中的表 list 创建user表&#xff0c;里面包含info&#xff0c;date两个列族 create user,info,data create user,{NAME > info, VERSIONS > 5},{NAME > data , VERSIONS > 5 } 插入数据 puthbase> put ns1:t1, r1, c1, …

类的无参方法

一、方法&#xff1a; 1.组成&#xff1a;访问修饰符&#xff08;public&#xff09; 返回值类型&#xff08;void,String ,int&#xff09; 方法名&#xff08;采用驼峰命名法&#xff09;(){ //方法体 } eg:public String run(){ //方法体 return “快跑”; } 注意&#xff1…

这些保护Spring Boot 应用的方法,你都用了吗?

转载自 这些保护Spring Boot 应用的方法&#xff0c;你都用了吗&#xff1f; Spring Boot大大简化了Spring应用程序的开发。它的自动配置和启动依赖大大减少了开始一个应用所需的代码和配置量&#xff0c;如果你已经习惯了Spring和大量XML配置&#xff0c;Spring Boot无疑是…

.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.…

路径、形状工具与选区

一、路径工具&#xff1a; 可以转换为选区或者使用涂颜色填充和描边的轮廓。 二、路径工具的功能&#xff1a; 1.绘制平滑线条 2.绘制矢量形状 3.勾选图像轮廓 4.选区互换 三、路径工具的分类&#xff1a; 1.路径选择工具&#xff1a;选择一个闭合的路径或者是一个独立存在的路…

zookeeper 屁民

视频链接&#xff1a;https://pan.baidu.com/s/1b_liTHLVCesMWqoZYokxyA 密码&#xff1a;wjgu 视频在 00:31:00–01:03:00之间 Zookeeper Server最基础的东西是什么呢&#xff1f;我想应该是Paxos了。所以本文会介绍Paxos以及它在ZK Server中对应的实现。 先说Paxos&#x…

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

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

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

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

滤镜与通道

一、滤镜&#xff1a;在原有图像的基础上&#xff0c;产生许多离奇而炫目的效果的工具集合。 二、滤镜分为两个部分&#xff1a; 1.内置的滤镜 2.外挂滤镜 三、滤镜组&#xff1a; 1.渲染&#xff1a;可以在图像中创建三维形状&#xff0c;云彩图案和三维光照效果。 2.风格化&a…

Zookeeper 详讲(笔记)1

client发送request给follower,follower将request给leader&#xff0c;leader将proposal&#xff08;提议&#xff09;发送给所有的follower&#xff0c;follower进行投票&#xff0c;每一个follower返回一个ack给Leader&#xff0c;leader将commit发送给所有的follower进行更新…

React的列表渲染

//9. 列表渲染class List extends React.Component{state {list:[1,2,3,4,5],list2:[{id:1,text:java},{id:2,text:js},{id:3,text:php},{id:4,text:python},{id:5,text:node}]}render(){const arr this.state.list;const arr2 this.state.list2;const listItem []const li…

Spring-SpringMVC父子容器

转载自 Spring-SpringMVC父子容器 前言 Spring&SpringMVC作为bean管理容器和MVC默认框架&#xff0c;是大多数web应用都会选择的方案。在其使用过程中&#xff0c;尽管基于xml的配置bean管理的方式依然存在&#xff0c;但在很多情况下已经采用的强大的注解功能将其替代。…

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

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

图标设计

一、图标的作用&#xff1a; 1.吸引用户的注意力 2.跨语言障碍&#xff0c;更好的实现人机交互。 二、图标的尺寸&#xff1a; 1.128128 2.4848 3.256256 4.3232 5.16*16 三、icon的中文意思就是图标&#xff0c;图形化表示。 四、图标的色彩数量&#xff1a; 1.颜色数&#xf…

React中后台管理系统添加广告分类显示不出来

问题描述 添加广告分类之后&#xff0c;其他的页面能正常显示&#xff0c;看不到广告页面&#xff0c;或者看到广告页面不停的转圈(打开network看到client的拦截信息) 问题分析 可能是浏览器中的拦截器拦截了请求 解决办法 关闭浏览器中的拦截广告插件

自定义机架感知

副本节点的选择&#xff08;机架感知&#xff09; 1、默认情况下 第一个副本在client所处的节点上&#xff0c;如果客户端在集群之外&#xff0c;&#xff08;在win7上运行程序&#xff0c;写文件到集群上&#xff09;&#xff0c;随机选一个。 第二个副本和第一个副本在不同…