当前位置:  编程技术>综合
本页文章导读:
    ▪C#4.0新特性(3):变性 Variance(逆变与协变)       原文出自:C#4.0新特性(3):变性 Variance(逆变与协变)   一句话总结:协变让一个粗粒度接口(或委托)可以接收一个更加具体的接口(或委托)作为参数(或返回值);逆变让.........
    ▪C#4.0新特性(2):Named and Optional Arguments 命名参数和可选参数       原文出自:C#4.0新特性(2):Named and Optional Arguments 命名参数和可选参数 为什么需要开放命名参数和可选参数呢? 这是出于动态语言运行时兼容性的要求。动态语言中存在动态绑定的参.........
    ▪TDD的不足之处            TDD有很多优点,但也有可改进之处,主要在三方面:自动化程度低、对资源利用不充分、干扰编程思维。     1.自动化程度低     TDD要求先编写测试代.........

[1]C#4.0新特性(3):变性 Variance(逆变与协变)
    来源: 互联网  发布时间: 2013-11-05


原文出自:C#4.0新特性(3):变性 Variance(逆变与协变)


  一句话总结:协变让一个粗粒度接口(或委托)可以接收一个更加具体的接口(或委托)作为参数(或返回值);逆变让一个接口(或委托)的参数类型(或返回值)类型更加具体化,也就是参数类型更强,更明确。

  通常,协变类型参数可用作委托的返回类型,而逆变类型参数可用作参数类型。对于接口,协变类型参数可用作接口的方法的返回类型,而逆变类型参数可用作接口的方法的参数类型。

协变

我们先来看下面一个来自MSDN的例子:

01 // 协变

    
[2]C#4.0新特性(2):Named and Optional Arguments 命名参数和可选参数
    来源: 互联网  发布时间: 2013-11-05


原文出自:C#4.0新特性(2):Named and Optional Arguments 命名参数和可选参数


为什么需要开放命名参数和可选参数呢?
  • 这是出于动态语言运行时兼容性的要求。动态语言中存在动态绑定的参数列表,有时候并不是所有的参数值都需要指定(有些语言可能没有重载决策);
  • 另外,在一些 COM 互操作时,往往 COM Invoke 的方法参数列表非常的长(例如 ExcelApplication.Save,可能需要 12 个参数),但 COM 暴露的参数的实际值往往为 null,只有很少一部分参数需要指定植,如 ExcelApplication.Save(),可能不需要指定任何参数值,或者仅仅一个值,例如 fileType。为了精简书写的代码,就有着这个特性。

命名参数和可选参数是两个截然不同的功能,但通常一起使用。在进行成员调用时,可以忽略可选参数;而命名参数的方式可以通过名称来提供一个参数,而无需依赖它在参数列表中出现的位置。

有些API——尤其是COM接口——如Office自动化API——确实本身就是通过命名参数和可选参数编写的。之前在C#中调用这些API非常痛苦,尤其有的时候需要多达30几个参数都必须显式传递,而其中大多数都具有合理的默认值,是可以忽略的。

即便是编写.NET中的API,你也会发现很多时候你在被迫为不同的参数组合方式编写一个方法的大量重载形式,以便给调用者提供最高的可用性。在这种情况下,可选参数就会成为一种非常有用的替代方式。

Named parameters 命名参数

有了命名实参,您将不再需要记住或查找形参在所调用方法的形参列表中的顺序。 可以按形参名称指定每个实参的形参。 例如,可以采用标准方式调用计算身体质量指数 (BMI) 的函数,方法是依照该函数定义的顺序按位置发送体重和身高的实参。

CalculateBMI(123, 64);

如果不记得形参的顺序,但却知道其名称,您可以按任意顺序(先发送体重或先发送身高)发送实参。

CalculateBMI(weight: 123, height: 64);

CalculateBMI(height: 64, weight: 123);

命名实参还可以标识每个实参所表示的含义,从而改进代码的可读性。

命名实参可以放在位置实参后面,如此处所示。

CalculateBMI(123, height: 64);

但是,位置实参不能放在命名实参后面。 下面的语句会导致编译器错误。

//CalculateBMI(weight: 123, 64);


    
[3]TDD的不足之处
    来源: 互联网  发布时间: 2013-11-05

 

    TDD有很多优点,但也有可改进之处,主要在三方面:自动化程度低、对资源利用不充分、干扰编程思维。

    1.自动化程度低

    TDD要求先编写测试代码再编写产品代码,这个编码顺序决定了难以利用工具来生成测试代码。当然,工具也不可能根据测试代码来生成产品代码。如果首先编写产品代码,工具则可以自动生成大部分测试代码,人工一般只需要设定用例的输入输出就可以了。测试代码的编写工作量是很大的。

    TDD要求先编写测试代码的理由主要有两点:一、这是设计行为,可以明确代码需求和设计;二、强制测试,避免先编写产品代码后,忽略测试。

       编写测试代码确实是一种很好的设计行为,但是如果进一步分析,“设计”主要体现在设定用例的输入输出上。假如我们不编写测试代码,而是用表格列出每个用例的输入输出,设计效果与编写测试代码差别不大。

       在编写一个类的测试代码前,难道不需要在心里想清楚类名是什么,父类是什么?在编写一个函数的测试代码前,难道不需要想清楚函数原形,如函数名,返回类型、参数个数、参数类型、参数名?如果这些不确定,如何编写测试代码?在心里想和写出来有本质区别吗?

       如果先编写产品代码的框架,包括类定义和函数原形,则可以用工具生成大部分测试代码。在编写函数的具体实现前,再定义用例,然后再编写代码,其结果和纯粹的TDD有什么区别呢?但效率则可以大幅提升。

      TDD一般使用开源框架,工具缺少自动化功能,遇到问题时很容易卡住,耽误大量时间。例如可测试性,虽然先编写测试代码有利于提高产品代码可测性,但仍然有很多可测性问题无法消除,举个简单的例子:函数中使用了局部静态变量,这种变量,在测试时一般要与全局变量同等对待,每个用例也要设定不同初值,但用例中却不能访问,如何解决?难道为了提高可测性,把局部静态变量都改为全局变量?

      2. 对资源利用不充分

       单元测试的输出可以完整描述程序的行为。程序行为就是在什么输入下,会执行哪些代码,会产生什么输出。写代码时如果能随时察看程序行为,就比较容易想明白思路对不对,接下来应该怎么写,容易找出错误原因,不但效率高得多,也没那么累。

       只要做了单元测试,反映程序行为的数据就一定会存在,这些数据是一种宝贵的资源,工具可以自动捕获,从而让程序行为可视,TDD忽略了这一点。一般的开源框架,只对输出数据进行了判断,只显示测试是否通过,不能显示所有的输入与输出数据,也不能显示用例所执行的代码。

很多时候,实现一个用例对应的功能点是很复杂的,代码可能有几十行,只有等到该功能点写完,程序员才知道测试是否通过。在编写一个功能点的过程中,程序员可能希望每写几行代码,就看看程序做了什么,以便检查和调整思路,找出和修改错误,这是TDD做不到的。

     3.干扰编程思维

      程序员是坚强的,而灵感、创意、思路则是脆弱、易失的。编程工作需要连贯的专注。TDD过程中,编写测试代码大概占用一半时间,而且与编写产品代码交替进行,难免影响编程思维的连贯性。当遇到难题,测试工作卡住时,对开发思维的干扰就更大了。这大概也是很多程序员不愿意编写测试的原因吧。

作者:wangwencong 发表于2013-1-5 15:53:14 原文链接
阅读:32 评论:0 查看评论

    
最新技术文章:
 




特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3