一,代码协定

代码协定通常称作契约式编程,包括如下三个部分:

  1. 前置条件(precondiction):为了调用函数,必须为真的条件,在其违反时,函数决不调用,传递好数据是调用者的责任。
  2. 后置条件(postcondion):函数保证能做到的事情,函数完成时的状态,函数有这一事实表示它会结束,不会无休止的循环
  3. 类不变项(class invariant):从调用者的角度来看,该条件总是为真,在函数的内部处理过程中,不变项可以为变,但在函数结束后,控制返回调用者时,不变项必须为真。

二,安装插件

要使用代码协定,首先需要安装Code Contracts for .NET插件。

安装插件后,可以在项目的属性页中的Code Contracts标签来配置相关选项:

勾上"Perform Runtime Check"选项,只是可以看到右侧的下拉框有五个选项,这里分别介绍一下它们的区别:

  1. Full表示执行所有的代码协定语句。
  2. Pre and Post表示执行前置和后置条件检查,即Contract.Require和Contract.Ensures。
  3. Preconditions 表示只执行前置条件检查,即Contract.Require。
  4. ReleaseRequires 表示执行public类的public方法的前置条件检查。
  5. None表示不执行代码协定检查,即不进行代码协定注入。

三,前置条件

    前置条件检查传递给方法的参数。使用Contract类中的Requires()方法可以定义前置条件。

public static void MinMax(int min, int max){Contract.Requires(max>min);            //...}

调用:

MinMax(1,1);

因为不满足前置条件,会报出异常:

Require()方法的重载方法:

public static void Requires(bool condition);
public static void Requires(bool condition, string userMessage);
public static void Requires<TException>(bool condition) where TException : Exception;
public static void Requires<TException>(bool condition, string userMessage) where TException : Exception;

例如,使用Requires方法的泛型变体可以指定当条件不满足时,调用的异常类型。如果参数o为空,下面的协定就抛出一个ArgumentNullException异常:

        public static void Preconditions(object o){Contract.Requires<ArgumentNullException>(o!=null,"Preconditions,o may not be null");}

为了检测用作参数的集合,Contract类提供了Exists()和ForAll()方法。ForAll()方法检测集合中的没一项,看看他们是否满足条件。

public static void ArrayTest(int[] data){Contract.Requires(Contract.ForAll(data,i=>i<12));}

四,后置条件

    后置条件定义了方法执行完后共享数据和返回值的保证。尽管后置条件定义了关于返回值的一些保证,但他们必须放在方法的开头;所有的协定要求都必须放在方法的开头。

        static void PostCondition(){Contract.Ensures(sharedState<6);sharedState = 9;Console.WriteLine($"change sharedState invariant {sharedState}");sharedState = 3;Console.WriteLine($"before returing change it to a valid value {sharedState}");}

Ensures()方法的重载方法:

public static void Ensures(bool condition);
public static void Ensures(bool condition, string userMessage);

为了保证返回某个值,可以对Ensures()方法的协定使用特定的值Result<T>

static int ReturnValue(){Contract.Ensures(Contract.Result<int>()<6);return 3;}

还可以比较新旧值。为此应使用OldValue<T>()方法,它返回在方法入口给变量传递的初始值。

        static int ReturnLargerThanInput(int x){Contract.Ensures(Contract.Result<int>()>Contract.OldValue<int>(x));return x + 3;}

五,类不变项

不变量为对象生命周期中的变量定义了协定。Contract.Requires()方法定义了输入要求,Contract.Ensures()方法定义了方法结束时的要求。Contract.Invariant()方法定义了在对象整个生命周期中都必须满足的条件。对Contract.Invariant的调用只能放在应用了ContractInvariantMethod特性的方法内。

        private int x = 5;[ContractInvariantMethod]public void ObjectInvariant(){Contract.Invariant(x>5);}

部分内容参考了:代码协定(一)——简介

转载于:https://www.cnblogs.com/khjian/p/5715421.html

《C#高级编程》读书笔记(十四):代码协定相关推荐

  1. 文件和目录(二)--unix环境高级编程读书笔记

    在linux中,文件的相关信息都记录在stat这个结构体中,文件长度是记录在stat的st_size成员中.对于普通文件,其长度可以为0,目录的长度一般为1024的倍数,这与linux文件系统中blo ...

  2. 《联邦学习实战》杨强 读书笔记十四——构建公平的大数据交易市场

    当数据具有资产属性之后,数据便可以直接或者间接地为公司.为社会创造价值和收益,并且可以作为一种特殊的商品在市场中进行交易. 与传统的商品交易相比,数据资产交易的市场前景更广阔,但同时也面临着很多的挑战 ...

  3. 《把时间当作朋友》读书笔记(十四)--积累(二)

    节省与否 有些钱真不能省,否则注定"屌丝"一生,因为这种"节省"可能会伴随有很高的隐性成本,或者将来造成很大的负担----今天看来省了,可将来却要因此付出极大的 ...

  4. How tomcat works 读书笔记十四 服务器组件和服务组件

    之前的项目还是有些问题的,例如 1 只能有一个连接器,只能处理http请求,无法添加另外一个连接器用来处理https. 2 对容器的关闭只能是粗暴的关闭Bootstrap. 服务器组件 org.apa ...

  5. WCF 4 高级编程 - 读书笔记

    第2章 服务契约与数据契约 在SOA架构中,契约提供了服务通信所必需的元数据.契约用来定义数据类型.操作.消息交换模式和消息交换使用的传输协议.契约通常是XML格式发布的.在WCF中,服务元数据通常是 ...

  6. linux系统数据文件和信息--unix环境高级编程读书笔记

    linux系统中的数据文件有很多,在这一章里介绍的主要内容是和系统有关的一系列文件,包括passwd,shadow,group,utmp,wtmp以及一些系统的相关信息和时间的相关操作. 1.pass ...

  7. 标准IO库--unix环境高级编程读书笔记

    标准IO库是C语言提供的一个库,不光存在于linux中,在windows中也是有的.标准IO库和文件IO的不同是,标准IO库是对文件IO(即系统调用)的封装,并且在用户层添加了一些缓冲区. 文件IO的 ...

  8. 文件io(一)--unix环境高级编程读书笔记

    unix-like(后面以linux为例)系统中的文件操作只需要五个函数就足够了,open.close.read.write以及lseek.这些操作被称为不带缓存的io,这里有必要说一下带缓存和不带缓 ...

  9. 高级IO(一)--UNIX环境高级编程读书笔记

    在前面学习了文件IO,标准IO和终端IO,现在学习高级IO,UNIX中怎么有这么多的IO. 1.非阻塞IO 可以将系统调用分为两类:低速系统调用和其他.低速系统调用是可能会使进程永远阻塞的一类系统调用 ...

  10. 终端IO--unix环境高级编程读书笔记

    终端IO部分整体上读了两遍,感觉这一部分的内容又乱又碎,不太好理解.读完了之后,仍然感觉什么也没有学到.先做一个肤浅的记录,等到以后要用到的时候,再回来补充. 1.终端IO的工作方式 终端IO有两种不 ...

最新文章

  1. 机器学习预测农民是否可以得到贷款
  2. linux 进程隐藏常见方法
  3. POJ 1655 Balancing Act (树的重心)
  4. 内核编译(make)
  5. python expect_python--pexpect
  6. Java 并发编程之 volatile
  7. python 处理异常_Python异常处理– Python尝试除外
  8. python网站开发实例 flask_Python Web开发之——构建基于Flask框架的web后端项目
  9. 远程计算机ip记录怎么删除吗,远程桌面连接清除登陆过的IP地址
  10. 无人机,动力系统建模
  11. 在R和Python中求峰度和偏度
  12. 快手投放广告,快手广告优势有哪些呢?
  13. Texmacs中文支持
  14. 男生为什么不追女生?
  15. 阿里云培训-OSS(对象存储)
  16. HDU 6194 string string string :后缀数组+单调队列 | 后缀自动机
  17. 成功解决mingw下载太慢的问题
  18. 怎样制作FL Studio步进音序器中的节奏
  19. Redis保姆级学习教程
  20. 东北林业大学计算机考研资料汇总

热门文章

  1. 服务器租用哪家靠谱?
  2. Cocos2d-X开发教程-捕鱼达人-欧阳坚-专题视频课程
  3. Web分辨率以及网页测试
  4. Linux内核与安全
  5. 23种设计模式-行为型模式-观察者模式
  6. 【转】IE主页无法修改,IE设置无法保存解决方案
  7. NBA球员信息盘点(数据分析)
  8. Go语言中的Interface
  9. 【JAVA秘籍功法篇-SpringBoot】初识SpringBoot
  10. 闪光灯的 E-TTL 模式