程序世界有两种神秘的元素,它们无处不在,却常常未被察觉。它们一动一静,却又和谐相处。我给 这对兄弟取上不太恰当的名字,一个叫“协议”,一个叫“约束”。我们常常看到的动态语言、静态语言 背后,本质上就是“协议”与“约束”两种元素的作用。静态语言和动态语言本身没有一个明确的界限, 它们各有优势,又各有不足。
C#是一门优美的语言,它融合了静态和动态的优势,如果运用得当,必能动静结合,呈现出一种和谐 之美。特别是.NET平台和语言的快速发展,更展现了动静结合编程的活力。本篇是.NET动静结合编程的第 一篇,希望这个系列能和大家一起探讨如何在.NET平台上最大限度的发挥动静结合的潜能。本人还只 是.NET的初学者,对计算机理论的理解还很肤浅,文中错误欢迎批评指正,不足之处欢迎补充,谢谢!
被忽略的协议
谈到“协议”,最先浮现在我们脑海中的可能是TCP/IP协议栈,但其实我们随处都在和协议打交道。 下面的例子,你看出协议来了吗?
B(){
ArrayList lst = A();
foreach (string item in lst){
Console.WriteLine(item.Length);
}
}
方法B假定方法A遵守:返回的ArrayList内部都是string类型的元素。这就是它们之间的协议,这个协 议不受编译器静态检查的约束。所以,协议意味着运行时的不确定性,方法A完全可能在返回结果中装入 非string类型的元素,而这将导致B在运行时产生异常。
.NET2.0通过泛型集合增加了静态类型约束:
B(){
List<string> lst = A();
foreach (string item in lst){
Console.WriteLine(item);
}
}
这样,B再也不用担心lst内部存在非string类型的元素了,一切得益于泛型为A加上的静态类型约束。
约束有强弱
约束有强弱之分。越强的约束越安全,静态性越强,受编译器的支持越大;反之,越弱的约束,动态 性越强,运行时灵活性越大。
常常看到关于单方法接口和委托异同的讨论,不少朋友认为它们完全等价。其实,它们有明显不同的 约束强度。接口是静态类型约束,而委托只是静态签名约束,二者的强度完全不同。换句话说,委托具有 更多的协议性,只要符合签名,都可以被委托调用,而能被接口调用的对象必须实现该接口。