AI 年度盘点与2025发展趋势展望,50+案例解析亮相AICon 了解详情
写点什么

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

  • 2017-04-17
  • 本文字数:1919 字

    阅读完需:约 6 分钟

类型类是另外一项正被考虑引入.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 答复说:

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

[……]

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

查看英文原文:.NET Futures: Type Classes and Extensions

2017-04-17 19:001990
用户头像

发布了 1008 篇内容, 共 392.1 次阅读, 收获喜欢 344 次。

关注

评论

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

支持向量机-非线性SVM与核函数

烧灯续昼2002

Python 机器学习 算法 sklearn 11月月更

2022-11-24:小团在地图上放了3个定位装置,想依赖他们进行定位! 地图是一个n*n的棋盘, 有3个定位装置(x1,y1),(x2,y2),(x3,y3),每个值均在[1,n]内。 小团在(a,

福大大架构师每日一题

golang 算法 福大大

JavaWeb项目部署到腾讯云教学

陈老老老板

腾讯云 javaWeb java; 11月月更

华为云GaussDB(for Influx):让智能电网时序数据处理更高效

路过的憨憨

华为

第三章 TCP/IP ip地址概念与应用

我叫于豆豆吖.

11月月更

广告业务存储神器:华为云GaussDB(for Redis)

秃头也爱科技

云数据库时代,DBA将走向何方?-v4

科技之光

【Python 基础学习】-变量和常量、输入输出

度假的小鱼

11月月更 Python变量常量 Python变量

支持向量机-探索核函数在不同数据集上的表现

烧灯续昼2002

Python 机器学习 算法 sklearn 11月月更

性能测试知识科普(六):三大模型

老张

性能测试 数据模型 业务模型 流量模型

C++--- 类型萃取 ---is_void && is_null_pointer

桑榆

C++ STL 11月月更

China SAFe Day 2022中国规模化敏捷大会圆满落幕!

Scrum中文网

敏捷 safe 规模化敏捷 SAFeDay

一文了解 Go 的复合数据类型(数组、切片 Slice、Map)

陈明勇

Go golang go基础 11月月更

“链游版羊了个羊”Matching Game即将登陆Gate

股市老人

【Python 基础学习】-基础语法

度假的小鱼

11月月更 Python基础语法

Web3领域首个三消小游戏Matching Game,近30交易量破800万U

BlockChain先知

【Python 基础学习】-运算符

度假的小鱼

11月月更 Python运算符 Python运算符优先级

【web 开发基础】PHP 中的可变参数个数的函数 (34)

迷彩

函数 web开发基础 11月月更 可变个数参数的函数

三分建设,七分运营|用现代化安全运营应对数据安全风险

爱科技的水月

软件架构的定义与分类

穿过生命散发芬芳

架构 11月月更

Mysql基础超详细讲解

陈老老老板

MySQL 数据库 11月月更

聊聊Mybatis的类型转换注册类TypeHandlerRegistry

急需上岸的小谢

11月月更

kitti数据集在3D目标检测中的入门(二)可视化详解

Studying_swz

人工智能 11月月更

聊聊Mybatis的数据源之获取连接

急需上岸的小谢

11月月更

成为数字游民,他们为何「All in Web3」?

One Block Community

程序员 web3 数字游民

Linux 文件基本属性

梦笔生花

chmod 11月月更 Linux文件属主 charp chown

华为云区块链三大核心技术国际标准立项通过

科技怪授

感恩每一位 RockStar!

StarRocks

数据库

如何使用Git进行代码托管

我是一个茶壶

git 代码托管 11月月更

聊聊Mybatis的类型转换接口TypeHandler

急需上岸的小谢

11月月更

.NET或将引入类型类和扩展_.NET_Jonathan Allen_InfoQ精选文章