关于C#语言支持using及foreach的看法

本文来自于博客园Jeffrey Zhao:

http://www.cnblogs.com/JeffreyZhao/archive/2010/07/02/1769803.html

firelong还有一些观点我是明白的,便是对于增加using和foreach这样的语言特性表示不满,觉得这是让语言变得臃肿,像foreach这样的设计模式,应该有类库提供。那么我们现在就来讨论一下这方面的问题吧。

using关键字

首先是using关键字,using关键字的作用是对IDisposable资源作管理,保证不会发生泄漏等问题。例如:

using 
(var 
stream = new 
FileStream
(""
, FileMode
.Create))
{
    // do something

}

那么,它又是怎么做的呢?其实效果是这样的:

var 
stream = new 
FileStream
(""
, FileMode
.Create);
try

{
    // do something

}
finally

{
    if 
(stream != null
)
    {
        stream.Dispose();
    }
}

看代码不说话。我想了解一下,您是喜欢直接写第二段代码,还是写using代码呢?

foreach关键字

foreach关键字是配合IEnumerable作遍历时使用的,比如这样的代码:

foreach 
(var 
i in 
source)
{
    Console
.WriteLine(i);
}

其实等价于:

using 
(var 
etor = source.GetEnumerator())
{
    while 
(etor.MoveNext())
    {
        Console
.WriteLine(etor.Current);
    }
}

咦,看上去并不复杂啊,只是多了一级缩进而已。不过您注意到没有,这里居然用到了“臃肿”的using关键字,所以说,这里的代码理应是这样写的:

var 
etor = source.GetEnumerator();
try

{
    while 
(etor.MoveNext())
    {
        Console
.WriteLine(etor.Current);
    }
}
finally

{
    if 
(etor != null
)
    {
        etor.Dispose();
    }
}

看代码不说话。我想了解一下,您是喜欢直接写第二段代码,还是写foreach代码呢?如果有两层foreach嵌套呢?

评价

firelong同学在文章中提到,用语言支持模式是一个设计上的错误,模式应该通过框架或类库来支持。这点我保留看法,因为在我看来,模式一定程 度上是为了弥补语言特性不足而设计的。因此,面向对象语言有面向对象语言的模式(如著名的GoF23),函数式编程也有函数式编程的模式(例如monad 应该可以算吧)。在C#,Python,Ruby里很少谈工厂方法模式,为什么?因为它们可以将函数作为方法的参数进行传递,不需要创建一个抽象类以及多 个实现。同样的,策略模式等等也是一样。因此,如果一个语言特性简化模式的使用,且这个模式非常常用,如using和foreach,那么这个语言特性很 有价值。

firelong同学在文章中回复到:“如果使用这种思路,那么Visitor模式,Adaptor模式等等难道也要加进来吗”,我觉得不能这样考虑问题,这有点类似“常见逻辑谬误 ”里的“滑坡谬误”,比如这种说法:

动物实验有损对生命的尊重。如果不尊重生命,即可能越来越容忍诸如战争及杀人等等暴力行为。那么,社会将很快就会沦为战场,人人都会时刻担忧自己的生命。这将是文明的末日。为了防止出现这种可怕结果,应当立即宣布动物实验为非法。

类比一下:

添加支持模式的语法有损语言的紧凑性。如果不考虑紧凑性,即可能越来越容忍诸如支持Visitor模式等等愚蠢行为。那么,语言很快就会沦为垃圾场,人人都会时刻担忧自己的代码。这将是程序的末日。为了防止出现这种可怕后果,应该立即废除对模式的语法支持。

其实每一个语法增加都是要权衡利弊的,例如using和foreach的确会大大简化开发,于是我很欢迎这个语法功能,而且如Iterator模式 的确是非常常用的。这点看一下您代码中有多少foreach便知道了——当然,有了LINQ之后,foreach用的很少,但是我很担心firelong 同学是否会支持LINQ所基于的多种语法特性。还有一方面,便是能否在语法上支持Visitor等模式,我没有想明白该怎么设计这个语法。我同样想不明白 的是,firelong同学说的,用框架类库来支持模式,就拿foreach和using来说,该怎么做才能像现在这样优雅呢?

其实foreach等功能都是现代语言的“标配”,Python,Ruby连Java都有支持Iterator的语法(如Python等还有如yield等Iterator生成器),而且在Java 7里,也已经加入像C#里using这样的自动资源管理(Automatic Resource Management,ARM) 功能,所以其实我不是很理解firelong所说的:用框架类库支持模式才是“正途”。我希望firelong同学能够补充更多理由。

猜你喜欢

转载自bandfor4.iteye.com/blog/1404510