设为首页 加入收藏

TOP

C#的未来:不可变类
2015-07-16 12:56:02 来源: 作者: 【 】 浏览:4
Tags:未来 可变

本文是 C# 的未来系列文章的最后一篇了,这次我们将讨论第 159 号提案,它建议在编译器中加入对不可变类的支持。虽说在 C# 中创建不可变类型一直以来都是可以做到的,并且C# 6 还将进一步简化这一过程,但目前还没有一种方式能够“将类声明为不可变”,并让编译器对这一声明进行校验。


这一提议看起来似乎并非十分重要,因为对类进行手动检查也不是非常困难的事。但如果缺少了对于不可变性的某种声明,就难以了解开发者的意图。应 用程序的开发者可能会做出某些假设,例如可以在多线程环境中安全地使用某个类,却发现在下一个版本中,类库的开发者为其加入了某个属性的 setter 方法,或是其它任何一种可变的、非线程安全的特性。


第 159 号提议推荐通过使用一个“immutable”关键字或者属性,显式地表明某个类型在任何情况下都不能更改。此外,一个不可变对象只能够引用其它不可变对象。


不可变对象的构造函数也具有一些限制,尤其是它们不能够通过“this”变量调用方法,因为这有可能将该对象在构造过程完成之前“泄漏”出去,从而破坏了对不可变性的承诺。至于这种泄漏应当引起一个错误还是一次警告,这一点可以再议。Sam Harwell 写道:


不可变性与 Pure


第一眼看上去,不可变性与 Pure(纯对象或方法)约束的作用似乎是相同的,但它们之间确实存在着一些重要的不同之处。


考虑到这些不同之处的存在,相信你会看到许多同时具有不可变性与 Pure 特性的对象。


泛型与不可变性


泛型类型也将支持不可变性。要实现这一点,通常需要为每个类型参数都设定一个不可变性的限制。但这一条规则还有待商榷,有人认为可以直接从类型的参数中推断出不可变性,而无需显式地将其列为不可变。


欺骗


在某些情况下,你必须对类型系统进行欺骗,这一点已经得到了认可。打个比方,ImmutableArray 是对一个普通数组的封装。而如果按照这条提议的基本原则来说,这种行为是不允许出现的。为了处理这种场景,你可以在这个类的标注中进行声明,表示你是有意 地违背了这条原则,并且已经仔细地考虑过这样做的后果。这种做法与“unsafe”关键字的行为很相似,因为后者也是为了这种场合才出现的。


由于“unsafe”关键字的意思已经固定了,因此该提议考虑使用其它的关键字。目前来说,得到最多认可的关键字是“mutable”,不过看起来大家对此都不是十分满意。


只读性 —— 隐式或显式


在一个不可变对象中,每个字段在语义上都是只读的。某些开发者认为不必显式地进行声明,这可以减少代码的冗长度。另一些人则认为,正如在静态类中声明静态字段一样,每个字段都应该显式地标注为只读。


内部或外部校验


具体在何处强制不可变性,这一点需要认真考虑。某些人认为,正如代码契约与 Pure 属性一样,不可变性也应当由某个外部分析器进行处理。这样一来,开发团队就能够自行决定是否需要以编程方式强制不可变性。


另一部分开发者则认为,正因为如此,不可变性更不应当由外部工具进行处理。他们希望编译器能够进行不可变性的检查,这样就不会在无意中破坏了它的不可变性。


来自于微软的 Jared Parsons 写道:


这种情况与 Pure 属性的承诺不同,后者只是表示在某个对象中的任何方法或是属性都不会“产生任何可见的状态更改”。


英文原文:C# Futures: Immutable Classes


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇在JavaScript 中创建JSON对象--例.. 下一篇Java与C在整数累加的运算对比

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: