8.1.2 在 C# 中把行为表示成函数

我们前面提到过,以面向对象的方式理解函数,就是把它认为是有一个单独方法的接口;从清单 8.1 的代码中,我们可以看到IClientTest 就是这样声明的。这样,测试可以很容易地表示成简单的函数;在 C# 中,我们可以使用lambda 函数来写测试:

Func<Client, bool> isRiskyYearsInJob=

client => client.YearsInJob <2;

不使用接口类型,现在,我们使用 Func<Client, bool>,它表示一个函数,把 Client 作为参数值,并返回布尔值。以这种方式写代码,可以显著减少围绕表示测试的表达式的程式化代码的数量。

正如可以在集合中保存实现某种接口的对象,我们也可以创建保存函数值的集合,在清单 8.2 中,List<T>类型就实现了这个功能。注意,我们创建了完全标准的对象集合,可以遍历集合中的所有函数,或者通过添加或删除某些函数值,实现修改集合。

初始化集合时,我们可以很容易地写代码,在单独一个方法中,指定一组默认测试。我们可以使用 lambda 函数语法添加测试,而无需预先声明函数,也可以使用 C# 3.0 的功能,称为集合初始化器(collection initializer),使语法更简洁。

清单 8.2用函数列表检查是否应该贷款(C#)

class Client {    [1] <-- 保存客户信息

public string Name { get; set;}

public int Income { get; set;}

public int YearsInJob { get; set;}

public bool UsesCreditCard { get;set; }

public bool CriminalRecord { get;set; }

}

static List<Func<Client, bool>>GetTests() {   <-- 返回测试列表

return new List<Func<Client,bool>> {  |

client =>client.CriminalRecord,       |

client =>client.Income < 30000,      | [2]集合初始化器,

client =>!client.UsesCreditCard,      |   创建测试列表

client =>client.YearsInJob < 2        |

};

}

清单 8.2 使用了 C# 3.0 中的许多新功能,由于这些功能,我们写的代码与 F# 的实现非常类似。首先,我们使用自动属性,声明一个保存有关客户信息类[1];接下来,我们实现一个方法,返回测试的集合。方法的主体就是一个return 语句,创建 .NET 列表类型,使用集合初始化器,初始化元素[2]。这种方法在创建集合时指定值,同样的方法也适用数组。在这个背后,它调用了集合的 Add 方法,但是这样更清晰。

保存在集合中的值,是使用lambda 函数语法写的函数。注意,我们不必指定 client 参数的类型,因为 C# 编译器知道 Add 方法的参数,与泛型类型参数相同,在我们的例子中,是Func<Client, bool>。

注意

以行为为中心的程序,能从库中动态加载新的行为,是很正常的要求。对于我们的应用程序来说,能够写一个 .NET 类库,包含 GetTests方法,将返回测试列表,像早前的代码一样;我们的程序在执行时调用这个方法,得到测试,执行测试时无需知道更多相关内容。

这可以使用System.Reflection 命名空间下标准 .NET 类来实现。典型的情况是动态加载程序集,找到程序集内所有适当的类,在运行时创建它们的实例。在本书的网站上可以找到有关使用反射的详细信息。

我们已经有一个类来表示客户,一个测试集合,告诉我们是否向客户提供贷款,现在,我们看看如何运行测试。

时间: 2024-09-21 00:20:35

8.1.2 在 C# 中把行为表示成函数的相关文章

SQL中的5种聚集函数

原文:SQL中的5种聚集函数 作为一个刚毕业进入这行的菜鸟,婶婶的觉的那种大神.大牛到底是怎样炼成的啊,我这小菜鸟感觉这TMD要学的东西这多啊,然后就给自己定了许多许多要学习的东西,可是有人又不停地给你灌输:东西不在多而要精通!我也觉得很有道理,可是怎样才能精通呢?封神之路,在哪里啊 !!! 这一天没有一个安静的心,基本是学不进去了,发现自己还是太功利了,急功近利!也许你只要学就行,管他是否能够立即让人见识到你的厉害,技术和知识这种东西也许还是要强调一个 底蕴的.既然自己最烦那种看了两篇文章就给

AngularJS指令中的compile与link函数解析

AngularJS指令中的compile与link函数解析 通常大家在使用ng中的指令的时候,用的链接函数最多的是link属性,下面这篇文章将告诉大家complie,pre-link,post-link的用法与区别. 原文地址 angularjs里的指令非常神奇,允许你创建非常语义化以及高度重用的组件,可以理解为web components的先驱者. 网上已经有很多介绍怎么使用指令的文章以及相关书籍,相互比较的话,很少有介绍compile与link的区别,更别说pre-link与post-lin

Linux中的shell脚本编程——函数

概述: 本章节将总结while,for循环语句的特殊用法,在不同的场景当中,更能发挥其功能和价值.除此之外,还会介绍一种特殊的循环语句select语句,实现菜单的作用.最重要的是讲解shell脚本编程中函数的用法.这些内容都要熟练掌握. 一.循环语句的特殊用法: 1.while循环的特殊用法(遍历文件的每一行): □语法:while read line; do 循环体 done < /PATH/FROM/SOMEFILE □意义:依次读取/PATH/FROM/SOMEFILE文件中的每一行,且将

eclipse中java项目转成Web项目

在eclipse导入一个myeclipse建的web项目后,在Eclipse中显示的还是java项目,按下面的步骤可以将其转换成web项目. 1.找到项目目录下的.project文件 2.编辑.project文件,找到<natures>...</natures> 3.2中找到的结点中加下面的的代码 <nature>org.eclipse.wst.common.project.facet.core.nature</nature> <nature>o

不能调用jquery中ready里面定义的函数?

现象:不能调用jquery中ready里面定义的函数 源码:<script type="text/javascript"> $(document).ready(function(e) { function test(){ alert('test!'); } }); test(); // 报错,test()未定义 </script> 解析:ready也相当于一个函数,即新建一局部函数作用域,外面 当然不可用.和js的onload函数差不多,就比如 function

dbus 创建Client过程中几个有用的函数

/**  * g_type_init:  *  * This function used to initialise the type system.  Since GLib 2.36,  * the type system is initialised automatically and this function does  * nothing.  *  * Deprecated: 2.36: the type system is now initialised automatically

MySQL中的内置系统函数

MySQL中的内置系统函数 用在SELECCT语句, 能及子句 where order by having 中 UPDATE DELETE, 函数中可以将字段名作为变量来用,变量的值就是这个列对应的每一行记录 一.字符串函数 php中用的函数,MySQl中大部也提供 1. CONCAT(S1,S2....SN): 把传入的参数连接成一个字符串 2. INSERT(str, x, y, insert): 将字符串X位置开始,y个字符串长度替换为字符串insert 3. LOWER(str) UPP

TSQL--按某字段列分组,在将各组中某列合并成一行

鉴于群里很多同事在问这个问题,我简单写个Demo,希望对初学者有帮助! 无真相,无解说,不解释,直接上Code! --================================================== --示例代码,仅供参考 --按照object_id分组,将同一组的name列的值合并在一起 SELECT OBJECT_NAME(T1.object_id) AS ObjectName , ( SELECT T2.name + ',' FROM sys.all_columns T

C++中拷贝构造函数和赋值函数被调用的时机

一.拷贝构造函数被调用的时机: 1. 当用类的一个对象去初始化该类的另一个对象(或引用)时系统自动调用拷贝构造函数实现拷贝赋值. 2. 若函数的形参为类对象,调用函数时,实参赋值给形参,系统自动调用拷贝构造函数. 3. 当函数的返回值是类对象时,系统自动调用拷贝构造函数. 二.赋值函数被调用的时机: 当用一个对象赋值给另一个对象时 注意一.二中初始化和赋值的区别 C++中拷贝构造函数和赋值函数被调用的时机,布布扣,bubuko.com