适合C# Actor的消息执行方式(6):协变与逆变
2010-09-30 20:50:09 来源:WEB开发网 闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閻愵剙鍔ょ紓宥咃躬瀵鎮㈤崗灏栨嫽闁诲酣娼ф竟濠偽i鍓х<闁诡垎鍐f寖闂佺娅曢幑鍥灳閺冨牆绀冩い蹇庣娴滈箖鏌ㄥ┑鍡欏嚬缂併劎绮妵鍕箳鐎n亞浠鹃梺闈涙搐鐎氫即鐛崶顒夋晬婵絾瀵ч幑鍥蓟閻斿摜鐟归柛顭戝枛椤牆顪冮妶搴′簼缂侇喗鎸搁悾鐑藉础閻愬秵妫冮崺鈧い鎺戝瀹撲礁鈹戦悩鎻掝伀缁惧彞绮欓弻娑氫沪閹规劕顥濋梺閫炲苯澧伴柟铏崌閿濈偛鈹戠€n€晠鏌嶆潪鎷屽厡闁汇倕鎳愮槐鎾存媴閸撴彃鍓卞銈嗗灦閻熲晛鐣烽妷褉鍋撻敐搴℃灍闁绘挻娲橀妵鍕箛闂堟稐绨肩紓浣藉煐濮樸劎妲愰幘璇茬闁冲搫鍊婚ˇ鏉库攽椤旂》宸ユい顓炲槻閻g兘骞掗幋鏃€鐎婚梺瑙勬儗閸樺€熲叺婵犵數濮烽弫鍛婃叏椤撱垹纾婚柟鍓х帛閳锋垶銇勯幒鍡椾壕缂備礁顦遍弫濠氱嵁閸℃稒鍊烽柛婵嗗椤旀劕鈹戦悜鍥╃У闁告挻鐟︽穱濠囨嚃閳哄啰锛滈梺褰掑亰閸欏骸鈻撳⿰鍫熺厸閻忕偟纭堕崑鎾诲箛娴e憡鍊梺纭呭亹鐞涖儵鍩€椤掑啫鐨洪柡浣圭墪閳规垿鎮欓弶鎴犱桓闂佸湱枪閹芥粎鍒掗弮鍫熷仺缂佸顕抽敃鍌涚厱闁哄洢鍔岄悘鐘绘煕閹般劌浜惧┑锛勫亼閸婃牠宕濋敃鈧…鍧楀焵椤掍胶绠剧€光偓婵犱線鍋楀┑顔硷龚濞咃絿妲愰幒鎳崇喓鎷犻懠鑸垫毐闂傚倷鑳舵灙婵炲鍏樺顐ゆ嫚瀹割喖娈ㄦ繝鐢靛У绾板秹寮查幓鎺濈唵閻犺櫣灏ㄥ銉р偓瑙勬尭濡繂顫忛搹鍦<婵☆垰鎼~宥囩磽娴i鍔嶉柟绋垮暱閻g兘骞嬮敃鈧粻濠氭偣閸パ冪骇鐎规挸绉撮—鍐Χ閸℃ê闉嶇紓浣割儐閸ㄥ墎绮嬪澶嬪€锋い鎺嶇瀵灝鈹戦埥鍡楃仯闁告鍕洸濡わ絽鍟崐鍨叏濡厧浜鹃悗姘炬嫹

在上一篇文章中,我们实现了一个简单的爬虫,并指出了这种方式的缺陷。现在,我们就来看一下,如何使用C# 4.0中所引入的“协变和逆变”特性来改进这种消息执行方式,这也是我认为在“普适Actor模型”中最合适的做法。这次,我们动真格的了,我们会一条一条地改进前文提出的缺陷。 协变与逆变
在以前的几篇文章中,我们一直挂在嘴边的说法便是消息于Actor类型的“耦合”太高。例如在简单的爬虫实现中,Crawler接受的消息为Crawl(Monitor, string),它的第一个参数为Monitor类型。但是在实际应用中,这个参数很可能需要是各种类型,唯一的“约束”只是它必须能够接受一个ICrawlResponseHandler类型的消息,这样我们就能把抓取的结果传递给它。至于操作Crawler对象的是Monitor还是Robot,还是我们单元测试时动态创建的Mock对象(这很重要),Crawler一概不会关心。
但就是这个约束,在以前的实现中,我们必须让这个目标继承Actor<ICrawlResponseHandler>,这样它也就无法接受其他类型的消息了。例如Monitor还要负责一些查询操作我们该怎么办呢?幸运的是,在.NET 4.0中,我们只需要让这个目标实现这样一个接口即可:
public interface IPort<out T>
{
void Post(Action<T> message);
}
瞅到out关键字了没?事实上,还有一个东西您在这里还没有看到,这便是Action委托在.NET 4.0中的签名:
public delegate void Action<in T>(T obj);
就在这样一个简单的示例中,协变和逆变所需要的in和out都出现了。这意味着如果有两个类型Parent和Child,其中Child是Parent的子类(或Parent接口的实现),那么实现了IPort<Child>的对象便可以自动赋值给IPort<Parent>类型的参数或引用1。使用代码来说明问题可能会更清楚一些:
- ››适合做商品团购营销的网站
- ››适合所有浏览器hack的CSS技巧
- ››消息称中国移动即将获得iPhone 4销售权
- ››适合C# Actor的消息执行方式(1):Erlang中的模式...
- ››适合C# Actor的消息执行方式(2):C# Actor的尴尬...
- ››适合C# Actor的消息执行方式(3):中看不中用的解...
- ››适合C# Actor的消息执行方式(4):阶段性总结
- ››适合C# Actor的消息执行方式(5):一个简单的网络...
- ››适合C# Actor的消息执行方式(6):协变与逆变
- ››适合1-5个月经验的seo优化全过程分享
- ››消息称联通高层赴美谈引入iPhone4 将带WiFi
- ››消息称微软将在近期发布IE9 beta
更多精彩
赞助商链接