`

关于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同学能够补充更多理由。

分享到:
评论

相关推荐

    微软C#语言规范,C#语言教程中文版

    5.3.3.16 foreach 语句 102 5.3.3.17 using 语句 102 5.3.3.18 lock 语句 102 5.3.3.19 yield 语句 102 5.3.3.20 简单表达式的一般规则 102 5.3.3.21 带有嵌入表达式的表达式的一般规则 103 5.3.3.22 调用表达式和...

    C#教程(语言规范)

    iv C#语言规范 2.4.1 Unicode 字符转义序列 ... 35 2.4.2 标识符. 35 2.4.3 关键字. 37 2.4.4 文本... 37 2.4.4.1 布尔值 .. 37 2.4.4.2 整数 ... 38 2.4.4.3 实数 ... 39 2.4.4.4 字符 ... 39 2.4.4.5 ...

    C# 语言规格说明(English Edition第五版)

    微软内部提供的详细描述C#语言结构和使用的文档,想做高级独立资深开发的不可错误,另外,此文档为英文原文版。建议作为平时学习阅读之用 目录: Table of Contents 1. Introduction 1 1.1 Hello world 1 1.2 ...

    C#中得到网卡号C#源代码

    C#中得到网卡号C#源代码 using System.Management; //get the MAC address ManagementClass mc=new ManagementClass("Win32_NetworkAdapterConfiguration"); ManagementObjectCollection moc=mc.GetInstances(); ...

    C#语言规范(2.0,3.0,4.0合集)

    这个是C#语言规范2.0,3.0,4.0的合集,是关于 C# 语法的权威资料。它们包含该语言各个方面的详细信息,包括 Visual C# 产品文档未涉及的许多语法点。 4.0目录 1. 简介 1 1.1 Hello world 1 1.2 程序结构 2 1.3 ...

    C#中foreach语句使用break暂停遍历的方法

    本文实例讲述了C#中foreach语句使用break暂停遍历的方法。分享给大家供大家参考。具体分析如下: 下面的代码演示了在C#中使用foreach时如何通过break语句暂停数据遍历 using System; public class w3demo { public...

    C# 获取U盘ID序列号及U盘信息

    可以获得U盘名称,制造商ID号 版本号 U盘序列号及容量 Form1.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; ...

    C#使用foreach语句遍历二维数组的方法

    本文实例讲述了C#使用foreach语句遍历二维数组的方法。分享给大家供大家参考。具体分析如下: 如果通过for语句循环遍历二维数组需要两重循环才可以,二foreach语句只需要一次可以完全遍历整个二维数组,下面是代码...

    C#语言规范4.0

    5.3.3.16 foreach 语句 102 5.3.3.17 using 语句 102 5.3.3.18 lock 语句 102 5.3.3.19 yield 语句 102 5.3.3.20 简单表达式的一般规则 102 5.3.3.21 带有嵌入表达式的表达式的一般规则 103 5.3.3.22 调用表达式和...

    C#使用foreach语句遍历集合类型的方法

    本文实例讲述了C#使用foreach语句遍历集合类型的方法。分享给大家供大家参考。具体如下: 这里演示如何实现可与 foreach 语句一起使用的集合类 using System; using System.Collections; public class Tokens: ...

    C#的elf文件解析库

    nupkg格式的C#库文件,专门用来解析elf类文件的,使用的时候先加载安装这个库,怎么安装自行百度C# nupkg, 然后using包含ELFSharp.ELF.XXX的命名空间,然后就可以操作对应的函数了, 实例: var elf = ELFReader....

    C#语言规范(4.0版本)

    Microsoft(微软)C#语言规范4.0版本,非常值得大家学习收藏! 目录 1. 简介 1 1.1 Hello world 1 1.2 程序结构 2 1.3 类型和变量 3 1.4 表达式 6 1.5 语句 8 1.6 类和对象 12 1.6.1 成员 12 1.6.2 可访问性 13 1.6.3 ...

    C#使用foreach遍历哈希表(hashtable)的方法

    本文实例讲述了C#使用foreach遍历哈希表(hashtable)的方法。分享给大家供大家参考。具体实现方法如下: using System; using System.Collection; namespace HashSampleApplication1 { class Program { static ...

    c#学习笔记.txt

    如前所述,我是一个狮子座男人,一度我认为学习Java会使我看起来与众不同,可是几个月以后我放弃了这个选择,我看了论坛里关于这两种语言孰优孰劣的讨论,最终选择了C#,请不要问我为何做出这样的选择,很多人认为...

    在一小时内学会 C#(txt版本)

    C# 是一种具有 C++ 特性,Java 样式及 BASIC 快速建模特性的编程语言。如果你已经知晓 C++ 语言,本文将在不到一小时的时间内带你快速浏览 C# 的语法。如果熟悉 Java 语言,Java 的编程结构、打包和垃圾回收的概念...

    C# 使用AForge调用摄像头

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using AForge....

    c# 获取已安装的打印机并调用打印文件

    C# 获取所有安装了的打印机代码如下: using System.Drawing.Printing; var printers = PrinterSettings.InstalledPrinters; foreach (var item in printers) { Console.WriteLine(item.ToString()); } C# ...

    C#面向对象考试题目

    非常齐全的C#考试题目 在C#程序中,下列用来处理异常的结构,错误的是( )。 a) catch{}finally{} b) try{}finally{} 在C#中,下列变量定义与赋值正确的是( )。 a) int age=12.5; b) string name = sodi; ...

    C#使用foreach语句搜索数组元素的方法

    本文实例讲述了C#使用foreach语句搜索数组元素的方法。分享给大家供大家参考。具体分析如下: 下面的代码通过foreach语句对数组遍历,然后对元素进行逐个比较的方法来查找数组中的元素 using System; public class ...

    C#5.0本质论第四版(因文件较大传的是百度网盘地址)

    C#5.0本质论第四版,高清扫描的,对C#5.0技术讲的比较详细,第1章 C#概述 1 1.1 Hello,World 1 1.2 C#语法基础 3 1.2.1 C#关键字 3 1.2.2 标识符 4 1.2.3 类型定义 5 1.2.4 Main 6 1.2.5...

Global site tag (gtag.js) - Google Analytics