.NET 4特性聚焦:代码契约

简介: 去年,我们已经开始在讨论Spec#,这是一个基于C#的支持通过契约来进行设计的语言。以契约来设计是构建于诸如静态类型化这样的概念之上的,特定的动作只有在编译时被验证之后才能执行。契约通常使用前置和后置条件的形式来表示,比如一个参数或返回值永远不能为空或者只能包含某个特定范围的值。
去年,我们已经开始在讨论 Spec#,这是一个基于C#的支持通过契约来进行设计的语言。以契约来设计是构建于诸如静态类型化这样的概念之上的,特定的动作只有在编译时被验证之后才能执行。契约通常使用前置和后置条件的形式来表示,比如一个参数或返回值永远不能为空或者只能包含某个特定范围的值。
 
为了不让开发人员学习整个诸如Spec#这样的新语言,微软正在构建一个独立于语言的函数库,可以被任何.NET语言所利用。在某些方面,契约 看上去类似断言,不过它们本质上存在非常大的区别。契约通过静态代码分析的组合来实现,它能被用于编译器内部和外部,以及测试框架之中。它们也能被执行, 这意味着它们在运行调试版本的时候和断言很类似。让我们来看第一个例子:
string GetDescription(int x){
Contract.Requires(x>0);
Contract.Ensures(Contract.Result() != null);
如果只看签名,开发人员只能获得静态类型的信息“GetDescription要求输入一个整数并返回一个字符串”。而通过附加契约,开发人员和工具都可以知道“GetDescription要求输入一个正整数并返回一个不能为空的字符串”。
 
除了显式的契约之外,契约检查器也支持隐式的契约。一个例子就是被零除这样的情况。如果一个类包含一个整数除法,其中的除数是一个变量,那么所 有的代码路径都必须保证这个变量不会为零或者会引发一个警告。如果在这种情况中的变量是一个开放类的属性,那么它也会要求检查每个子类。对于非关联化空值 和数组索引也存在一些隐式契约。
 
为了让契约设计更容易,还存在一个ObjectInvariant方法的概念。这个特别的方法只包含契约,可以被注入到每个方法调用的末尾以保证对象的状态保持一致。要着重注意的是,这个东西要应用到所有方法之中,包括那些来自于其他程序集的子类。
 
另外一个节省时间的功能是轻易对旧值的访问。在下面的例子中,Ensures契约被用于关联OldValue语法以确定集合的数目属性是递增的。
Public Sub Add(value as Object)
Contract.Ensure(Count = Contract.OldValue(Count) + 1) 
虽然契约是写在方法之上的,不过它能被编译器自动地移到Return语句之前。由于需要一些系统开销来存储Count的旧值,检查器的这种排序操作只在调试编译版本中发生。
 
为了支持函数库开发人员,发布版本包含了一个引用程序集。例如,Widgets.dll程序集拥有的大量契约被提取和放置到了程序集Widgets.Contracts.dll中。这允许客户端开发人员在利用由函数库开发人员创建的契约时,还是能使用更快的发布编译版本。
 
一个更有趣的特性是契约不仅仅能应用于实际的函数,甚至没有其他实现细节的接口和抽象方法也能拥有契约。这是通过创建这个接口的一个引用实现来实现,这个引用实现的唯一目的就是持有契约。而这个引用实现则通过特性以连接回接口。 
 
对于契约的内容没有任何限制。由于相同的契约可以用于静态和运行时检查过程,所以,一个不能被评估的约束可能仍然允许被其他的检查。契约也能被文档生成器提取为文档信息。
 
关于 .NET 4中的契约的更多信息,可以仔细阅读PDC主旨发言的前半部分。
 

查看英文原文:.NET 4 Feature Focus: Code Contracts

相关文章
|
3月前
|
API
【Azure 媒体服务】Media Service的编码示例 -- 创建缩略图子画面的.NET代码调试问题
【Azure 媒体服务】Media Service的编码示例 -- 创建缩略图子画面的.NET代码调试问题
|
16天前
|
安全 Java 网络安全
Android远程连接和登录FTPS服务代码(commons.net库)
Android远程连接和登录FTPS服务代码(commons.net库)
16 1
|
19天前
|
JSON C# 开发者
C#语言新特性深度剖析:提升你的.NET开发效率
【10月更文挑战第15天】C#语言凭借其强大的功能和易用性深受开发者喜爱。随着.NET平台的演进,C#不断引入新特性,如C# 7.0的模式匹配和C# 8.0的异步流,显著提升了开发效率和代码可维护性。本文将深入探讨这些新特性,助力开发者在.NET开发中更高效地利用它们。
28 1
|
29天前
|
存储 编译器
.Net特性Attribute的高级使用
【10月更文挑战第14天】在.NET中,特性(Attribute)是一种强大的机制,用于在代码中添加元数据。本文介绍了特性的高级用法,包括自定义特性、通过反射读取特性、条件编译与特性结合、多个特性应用以及特性继承。通过示例展示了如何创建自定义特性类、应用自定义特性,并通过反射获取特性信息。此外,还介绍了如何利用条件编译符号实现不同版本的代码控制,以及如何在一个代码元素上应用多个特性。最后,探讨了如何通过`AttributeUsage`控制特性的继承行为。
|
25天前
|
前端开发 JavaScript C#
CodeMaid:一款基于.NET开发的Visual Studio代码简化和整理实用插件
CodeMaid:一款基于.NET开发的Visual Studio代码简化和整理实用插件
|
3月前
|
Kubernetes 监控 Devops
【独家揭秘】.NET项目中的DevOps实践:从代码提交到生产部署,你不知道的那些事!
【8月更文挑战第28天】.NET 项目中的 DevOps 实践贯穿代码提交到生产部署全流程,涵盖健壮的源代码管理、GitFlow 工作流、持续集成与部署、容器化及监控日志记录。通过 Git、CI/CD 工具、Kubernetes 及日志框架的最佳实践应用,显著提升软件开发效率与质量。本文通过具体示例,助力开发者构建高效可靠的 DevOps 流程,确保项目成功交付。
73 0
|
3月前
|
XML 开发框架 .NET
.NET框架:软件开发领域的瑞士军刀,如何让初学者变身代码艺术家——从基础架构到独特优势,一篇不可错过的深度解读。
【8月更文挑战第28天】.NET框架是由微软推出的统一开发平台,支持多种编程语言,简化应用程序的开发与部署。其核心组件包括公共语言运行库(CLR)和类库(FCL)。CLR负责内存管理、线程管理和异常处理等任务,确保代码稳定运行;FCL则提供了丰富的类和接口,涵盖网络、数据访问、安全性等多个领域,提高开发效率。此外,.NET框架还支持跨语言互操作,允许开发者使用C#、VB.NET等语言编写代码并无缝集成。这一框架凭借其强大的功能和广泛的社区支持,已成为软件开发领域的重要工具,适合初学者深入学习以奠定职业生涯基础。
99 1
|
3月前
|
API
【Azure Key Vault】.NET 代码如何访问中国区的Key Vault中的机密信息(Get/Set Secret)
【Azure Key Vault】.NET 代码如何访问中国区的Key Vault中的机密信息(Get/Set Secret)
|
3月前
|
微服务 API Java
微服务架构大揭秘!Play Framework如何助力构建松耦合系统?一场技术革命即将上演!
【8月更文挑战第31天】互联网技术飞速发展,微服务架构成为企业级应用主流。微服务将单一应用拆分成多个小服务,通过轻量级通信机制交互。高性能Java Web框架Play Framework具备轻量级、易扩展特性,适合构建微服务。本文探讨使用Play Framework构建松耦合微服务系统的方法。Play采用响应式编程模型,支持模块化开发,提供丰富生态系统,便于快速构建功能完善的微服务。
47 0
|
3月前
|
SQL 开发框架 .NET
代码更简洁,开发更高效:从零开始使用Entity Framework Core与传统ADO.NET构建数据持久化层的比较
【8月更文挑战第31天】在.NET平台上开发数据驱动应用时,选择合适的ORM框架至关重要。本文通过对比传统的ADO.NET和现代的Entity Framework Core (EF Core),展示了如何从零开始构建数据持久化层。ADO.NET虽强大灵活,但需要大量手写代码;EF Core则简化了数据访问,支持LINQ查询,自动生成SQL命令,提升开发效率。从创建.NET Core项目、定义数据模型、配置`DbContext`到执行数据库操作,EF Core提供了一套流畅的API,使数据持久化层的构建变得简单直接。
33 0