程序员天地
robert hess和jeffrey richter(著名的编程作家、专栏作家和咨询专家)的谈话。
robert hess: 欢迎回来。我们正要涉及到有关c#编程方面的问题。为了有助于我们理解这些问题,我邀请我的好朋友jeffery richter到这里来。jeffery恰好是一名撰写了很多编程书籍的程序员,他最新的一本书为programming server side applications for windows 2000。现在您也是一位咨询专家并且拥有自己的公司wintellect,是吗?
jeffrey richter: wintellect。
robert hess: 我猜您有一个网站吧?
jeffrey richter:有,wintellect.com。我们专门从事培训、调试和广告。
robert hess: 好了,我了解到您最近做了不少有关c#的工作。
jeffrey richter: 是的,至今已一年有余了,我花了很大的精力一直专攻c#的编程。
robert hess:已经有一年了?我想我们才刚发布了c#。
jeffrey richter:是的,可我一直在圈内,在microsoft的圈内,如果您愿意的话。我自己在第42楼安置了一个小小的办公室,并在那里从事c#的研究和有关.net这方面的工作,到现在已经一年多了。
robert hess: 这样微软就会对您有所帮助,因为您并不是微软的职员……
jeffrey richter: 对。
robert hess:他们只是帮助您的把c#当成一种语言理解,那么您就可以写出更多象这样的书?
jeffrey richter:是的,他们希望我写更多的书,我得到了帮助,发现了bug,出席了类似的一些规范会议,并与人们交流,因此我觉得学到了很多的东西,而不只是写书,而事实在某种程度上也对c#做出了贡献。所以我可以告诉您,当最初开始时,我感兴趣的第一个东西就是这种新的语言,我将用它来写所有的代码,我知道这些代码是为可以预见的未来写的,让我们暂且不提。我具有非常深厚的c、c++背景,在阅读与c#相关文档和编程参考等资料一个星期之后,我就觉得已经相当精通c#了。并且在一周之内,我能够真正地写出一些有用的东西。
robert hess:仅仅一周之后。
jeffrey richter:是的,仅仅一周之后。因为它和c++非常类似,您知道,那里的大括号是相同的,返回值是相同的,参数是相同的,许多东西都是相同的。
robert hess:当继续使用对象、析构函数、构造函数、双冒号(::)等这些老掉牙的东西时,您似乎就要失去他们所拥有有的某些奇特的命名习惯,对吗?
jeffrey richter:是的是的,双冒号(::)都被点号(.)代替,箭头号(->)也被点号代替,这样就大大地简化了该语言。因而对于我来说实在是太容易啦,而且它还具有时效性,我仍不得不回过头去查看该语言参考资料,或许查找如何重载运算符,或者某些很平常的东西,要知道,当我编程时,极少做一些模糊不清的事。而现在大多数东西对我来说是再自然不过的了。事实上要解决的只是流程问题。
robert hess:既然您从事这项工作已经一年多了,那么您注意到了在这段时间里这种语言自身的演变吗?是否它们今天仍然与一年以前的十分相同?
jeffrey richter:我认为十分相同。但肯定存在着一些小技巧(tweak),在beta测试阶段确实存在着这些回应,存在着许多非确定性的析构函数(non deterministic destructor)、对象的析构(destruction of objects)等类似的东西。因此,基类库已经增加了一个idisposable接口,我想它将会出现在beta 2.0版中,而不是在beta 1.0版中。同时c#已增加了一些新的语言结构,以帮助你获得与对象的确定性析构(deterministic destruction of objects)关系密切的东西。所以我要说,微软已经十分在意人们对该语言的评价了,并且他们还企图在其中加入新的东西以做出回应。我同样了解到,将来在1.0版之后,他们计划要增加泛型(generics),这有点类似c++中的模板,而我可以肯定,为了支持这些性能,c#就要发展。实际上当处于公共语言运行库(common language runtime)之中时,所有的语言都能用到泛型。
robert hess:因为它们是其中的一部份,又因其是公共语言运行库,所以它们有权使用所有的那些功能。那么您认为,c#作为一种语言总的来说究竟怎么样?
jeffrey richter:嗯,正如我所说的,c#与c++非常相似,所以我很快便熟悉了。它非常非常的干净,我要说它是非常干净的。我出身于c++背景,尤其是作为一个windows c++程序员。ansii拥有c++规范,微软为了展示windows中的功能,就想在c++中保留一些技巧,并且使这些技巧看起来有点像c++中的贵族,可它们从来就没有真正地达到要求。而微软仍陆续增加__try、 __finally 和 __declspec等类似的东西。
robert hess:这就是您正在谈论的c#。
jeffrey richter:对,当然还有c++。因此,这种语言确实有点恐怖,过了一会儿您还是不会完全弄明白,就如const的用法,当声明一个指针或者是一个常量指针时,星号(*)究竟应放在它的前面,还是放在后面?您将无法断定这些修饰符到底应放在该行的那个位置。我总是需要查资料。因此在c#中,由于微软在设计时已经预先向ecma(欧洲计算机制造商协会)做出了要求标准化的提议,所以它实在很干净,例如,没有什么是以下滑杠开始的。当然,由于本来在.net runtime中就没有真正的指针,所以在您的代码中,从头到尾都不会能见到*号和&号等此类修饰符。这样当考虑它时,看起来干净,真的觉得很爽。
robert hess:难道您不觉得缺少什么吗?我的意思是,当我在用c编程时,喜欢运用指针解决问题,对指针重新分类,利用指针算法等老掉牙的东西,您就会从中获得极大的乐趣。难道您在用c#时就不怀念它吗?
jeffrey richter:嗯,我不得不承认,我自己总是有些喜新厌旧,但有时也有点念它。当然总的来说,有了c#和.net framework,您就可以始终与其它语言进行交互操作(interoperate out),因而如果真的必须那样做的话,我便用c++而不是c#编程了。c#也确实提供了一种不安全的关键词(unsafe keyword),这样一来,您就可以创建一个方法并且说,这是不安全的,您有权使用指针并对内存进行直接操作。尽管如此,我还是从未亲自体验过。至于编码时获得的乐趣,.net framework和基本os类库提供了大量的特性,它们使编程变得有趣了。因此,当我不能保留虚拟内存并稀疏地提交,也不能在.net framework中利用内存映象文件进行工作时,至少不能直接进行时,也可以通过交互操作完成,仍然还有其它类似serialization和web服务等东西,它们有利于创作出真正有价值的应用程序,真正强大而丰富的内涵。
robert hess:如今在您的培训班里,您正在教授和灌输这样的东西,您还在办c#的培训班吗?
jeffrey richter:是的,事实上刚好这一周,我给第一个c#编程班上课,当时班里有两个visual basic程序员,他们根本就不是面向对象的程序员,而我也没有真正地给他们介绍过c#语言,因为我把重点放在公共语言运行库和基类库方面,有关c#的内容想稍后再讲。但是,这两个vb程序员在上机实习时,对c#上手很快,几乎没有遇到什么麻烦,而且竟然能用其进行开发,效率也高。我十分惊讶!
robert hess:其中的原因是由于在c#中,您使用name.name.name.name,而不是name、->、name.name、-> name.*、*、()、&等老掉牙的东西……
jeffrey richter: 确实这样。
robert hess:这些在vb中都不会用到。
jeffrey richter:正确。
robert hess:所以格式看来相当一致。
jeffrey richter:对,相当一致。当然,他们用大括号{}而不是begin和end,这可能使有些人不适应。但我认为,他们最多花不到5分钟的时间就可以克服它,而且更多产。
rrobert hess:那么以一个公司的立场,假如一个公司聘请您去开设一个c#培训班,因此我得去发现他们是否开始考虑把公司的一些成果移植到c#,这就是您建议他们要做的事吗?或者您认为他们应处于哪一个阶段?
jeffrey richter:嗯,当然它取决于,首先他们必须决定是否要采用.net framework作为开发平台。我认为这非常有价值,对于我来说毫无问题,那是我真正向往的平台。如果您正在开发.net framework的应用软件,正在编写新的代码,在我看来会不费吹灰之力。 c#上手实在是很容易,它是一种生机勃勃的语言,使用正确的方法您会非常多产的。我个人也相信大量的vb程序员,vb6.0程序员,将会转向c#而不是vb7.0。
robert hess:那为什么?
jeffrey richter:因为我认为c#揭示了公共语言运行库(common language runtime)之中的更多的特性,使您对代码及其所表达的方法具有更多一点的控制权。您将更直接地与runtime对话,runtime赋予了您更多的权力。
robert hess:当然,我们本身谁都不是vb程序员,所以将明确地在c基础之上发展。
jeffrey richter: 您是对的。
robert hess:所以这正是它物有所值之处,我们有点偏离正题了。那么作为一种语言,您喜欢c#的哪些方面呢?是更简单、更彻底(clean)的编程吗?
jeffrey richter: 嗯,主要是去掉了无用的东西。 譬如, 嗯, c#不允许您把参数作为常量(const)声明,并且您不能拥有一个const的实体方法,而在c++中则可以。我知道某些人会认为那样会真的丧失语言的特性,但事实在c++中,const总是会被无情地抛弃,这样您就能在自己的代码中为所欲为了。由于c#实在是不允许您使用const,所以它又彻底又易于理解。现在,我想我应该说:对于我,.net frameworks真正有趣的东西就是公共语言运行库。它定义对象如何运转,或如何创建类型,以及是什么定义了这些类型的行为。这样您就拥有了一个基类库,当然它是一个巨大的类库,它让您有权使用大量的东西,所以即使您愿意,也不必再三重写每一样东西了。您选择语言是您个人的事情,而我选择了c#是由于它是真正优秀的高阶语言,它让我能与framework对话。但在某种程度上,运用.net runtime和基类库真正最佳的语言应该是中间语言(immediate language)汇编语言。
robert hess:哈!谈到汇编语言啦?
jeffrey richter:是的,谈到汇编语言了。我的意思是,它使您完全有权访问平台的底层,但在汇编语言的环境中效率会很低,有这么多的程序您必须一行一行地写。所以,c#语言高出了一个层次。而在c#中的有些性能并不是很常用,因此象anders 这样的c#设计者已决定不必将其公开了。在某些情况下,为了访问c#没有提供的runtime功能,我可能会求助于另外一种语言。但总的来说,c#是最高层的语言,它允许我在这样的环境中按自己的需求解决大量的问题,而且效率极高。
robert hess:并不是所有的问题,而仅仅只是大部份?
jeffrey richter:不,极少会出现这种情况:我还需要访问某些东西,而c#却不让访问。这是另外一方面,我只是认为大家非常容易忘却的是,当您想要访问.net的一些功能而c#或某些语言却不提供给您时,可以转到别的语言。只需编码创建这个方法,可能是一个静态方法(static method),类中的静态方法,用apl或cobol或凡是您选择的语言,或许派生,然后用某些语言实现实体方法,而这种语言可能真的让您访问某些底层功能。因此,我认为这是一个功能非常强大的范例,以前我从未真正地领会过要选择最佳的语言去完成工作。
robert hess:好了,我打赌各位观众可能想要看一些c#代码的例子,以便能理解我们谈论到的一些问题。您有例子示范给我们看吗?
jeffrey richter:有。我确实的带来了一个源代码文件,里面有一些例子,能勉勉强强地应付,在节目结束后,我会给您的。欢迎您把它上传到网站上,以让大家可以下载。所以在这里,如果你样喜欢的话,我首先要示范的是:在c#中,每一个方法必须位于类中。没有全局方法,也没有位于类之外的变量,所以每一样东西都会被限定在一定的范围内。
using system;
class app {
public static void main() {
console.writeline("hello world");
}
}
这是一个必须保留的hello world程序,非常简单。在程序里,有一个类叫app,在这个类里,我拥有自己的一个main方法,并且main是一个静态方法,因为它必须从外面调用。我们不必拥有app的一个实例就可以调用main。在我这个例子里,main返回void,并且没有接受参数。简单地在main的内部,它调用了console.writeline,在显示器上面显示出"hello world"。所以这是您可以写的、能学到相关概念的最小程序了。
robert hess:在c#中main仍然是一个保留的方法吗?就象在c++中?
jeffrey richter: main是默认的,它具有大写字母m,小写字母a-i-n ,因为c#是字母大小写敏感的语言,象c++ 而不象vb 和.net 。所以当编译器编译代码时,将寻找一个叫做main的静态方法,然后再使用它。然而有一个编译器的命令行,它可以覆盖掉main并选取其中不同的一个。顺便说一下,事实上这是一门很有用的技巧。一些人把多个main放到一个单个的应用程序里,以便进行组测试,当编译时,可以设置不同的开关执行不同的main,以便测试特定的组件。
robert hess:绝妙的技巧。您也使用象argv、 argc这样的参数,默认地传递给main函数吗?
using system;
class app {
public static void main(string[] args) {
console.writeline("hello world");
}
}
jeffrey richter:是,随您的便。在这里,我将当场修改这些代码,也就是说,string是一个字符串数组,args 按我在幻灯片中播放的定义。顺便地,这个args是什么呢?是一个数据类型!它是一个指向字符串的指针,或者是一个指向字符串的引用。说到指针,您只见过带*号的,但args确实是一个指针。当main被调用之前,启动代码早已解析命令行,并且创建一个字符串数组,接着把指针传入该数组。象对args.length类似的调用使我可以解决一些问题,该调用会返回数组的length属性,此属性含有数组元素的个数,然后我正好可以利用一个正常的for语句进行循环,或者可以用c#的for each,特殊的for each语句用于快速的循环。
robert hess:很新颖,这是在c或c++中所没有的。
jeffrey richter:正确。而我确实也有演示的代码,我找到了。
static void arraydemo() {
// 声明一个指向数组的引用
int32[] ia; // 默认值为 null
ia = new int32[100];
ia = new int32[] { 1, 2, 3, 4, 5 };
.
.
.
这是一个具有数组的代码的例子,所以我会略为提一下。在这个例子里,首先声明一个指向int32s数组的引用,随意取一个"ia"用于整数数组。它只不过是一个指针,具有32位(bit)或64位值,如果它们仍在64位系统上运行,总是会被初始化为null,引用总是被初始化为null直到明确地设置它为止。下面一行,我随意new(构造)了一个有100个int32值的数组。new返回一个引用,接着我把这个引用存到"ia"变量中。下一行只不过演示了另外一种构造的方式,这里我又new了一个int32s数组,这种专门的c#句法以一个左大括号开始,后面跟着数组的元素,当然元素之间要用逗号分开,然后是一个右括号。当您第一次见到这种句法时,会觉得它有点笨拙。这只不过是new的另外一种用法,当然它可以推算出元素的个数。
robert hess: 而这只不过是预定义了值:
.
.
.
// 显示数组的内容
foreach (int32 x in ia)
console.write("{0} ", x);
//使用多维数组
stringbuilder[,] sa = new stringbuilder[10][5];
for (int x = 0; x < 10; x++) {
for (int y = 0; y < 5; y++) {
sa[x][y] = new stringbuilder(10);
}
}
// 使用数组的数组(jagged arrays)
int32 numpolygons = 3;
point[][] polygons = new point[numpolygons][];
polygons[0] = new point[3] { ... };
polygons[1] = new point[5] { ... };
polygons[2] = new point[10] { ... };
}
jeffrey richter:是的,很正确。这就是foreach,它出现在代码的第一行。"foreach"是c#句法,我肯定所有的.net语言都会提供此句法,它是一个极其通用的编程典范,用这种方式,就可以遍历集合里的元素。因此,这里的foreach int32 x中,"x"是一个变量,int32当然是一种类型,接着我把引用赋予了数组。foreach将会自动推算出数组中有多少个元素,并且每当循环到console.write时,就会显示出元素的值,然后再移向下一个元素。
robert hess:而"for (i=0, i<ia.length, i++)"也做同样的工作,但如果您想要遍历所有的元素的话,这种方式有些笨拙以至难于遵循,所以一直持续不断地做十分相同的事情,我想会更加容易。
jeffrey richter:对,精辟。尽管如此,我会给您一点提示,由于foreach有点酷,也十分精巧,因此省去了大量的编码。它也另外做一些有关类型转换(casting)的工作,这对您同样也有好处。所以一般来说,当我写一个循环时,我通常会以foreach开始,然后当我继续编码时,有时经常地,我随后认识到我需要一个迭代器(iterator),需要一个从0到实际数字的x。是的,我必须知道哪一个元素号。所以我终止了重写这个循环,相当频繁……
robert hess: 噢,真的吗?
jeffrey richter: 是真的。
robert hess: 当作一个标准的for循环?
jeffrey richter:对,当作一个标准的for循环。因此有时到了最后,它所做工作比我当初想象的还要多。使用foreach是相当常见的,有了它实在是很爽。
robert hess:我猜您本来也应当在那里放置一个计数器,不过这会完全使foreach不起作用。
jeffrey richter: 是的,很正确。
robert hess:那么,您认为c#还另外具有什么样很酷特性,以让观众说,好,这就是我要选的语言?
jeffrey richter:嗯,正如anders在前面指出,c#是完全基于组件的,在那里具有事件,具有接口,具有属性,它们都是一等公民,所以没有下滑杠,没有下滑杠属性等任何类似的东西。出身于c#的人应当熟悉异常处理,因为遇到错误时,就调用在基类库中的framework里的错误处理程序。因此我在屏幕上写了一小块代码,以示范如何进行适当的错误处理。我具有一个try语块,再强调一下,您应注意在try这个单词的前面没有下滑杠,因为在c#语言中它位于第一阶层。我new一个文件流对象,这是打开磁盘里的文件的一种方式。而在双引号里,我给出了我们希望打开的文件的路径名。
using system;
using system.io;
public class app {
public static void main() {
filestream fs = null;
try {
fs = new filestream(@"c:\notthere.txt", filemode.open);
}
catch (exception e) {
console.writeline(e.message);
}
finally {
if (fs != null) fs.close();
}
}
}
robert hess:等等,那是一个错误,是吗?
jeffrey richter:不,这正是我要指出的。因为c#有一个非常酷的特性,可以给字符串加上一个@符号的前缀,使我们转用原义字符串(verbatim string,即真正的字符串,不加任何转义符),这里只允许使用单反斜杠“\”而不是双反斜杠“\\”。而长路径实在是一种十分常见的c++编程错误,人们以反斜杠代替双反斜杠,文件就不能正确地打开。在这种情况下应用加上"\n",意思是要换行。所以,这实在是一个巧妙的特性。不象一个file stream,因为人们熟悉win32的createfile函数,当该函数无法打开一个文件时就会返回无效的句柄值,或返回-1意味着失败。在.net framework中,当我企图打开一个不存在的文件时,就会引发一个异常,所以我在这里设置了一个catch语块,设法捕获到异常,这是一个非常简单的catch语块,只把信息输出屏幕,看看可能做了些什么,接着我又设置了一个finally语块,在这里的代码要确保能执行,因此假如我在try语块中有很多行真正涉及到文件操作的代码,在打开文件之后,finally语块就会执行并在最后明确地关闭文件。这实在是一种很巧妙的特性,win32甚至是c++也不曾拥有,它能够使try,catch和finally浑然一体,真正算起来,这种操作我们以前从未遇见过。
robert hess:我认为当应用程序变得越来越复杂时,人们在其中进行错误处理是相当重要的,当企图创建文件或进行类似的操作时,出错的机会可能会很多。尤其是使用其他人的对象和类似的东西时。
那么,这是不是意味着在编写c#的应用程序时,您必须保证函数和方法都能正确地设置异常并抛出一个异常,以便人们可以捕获它?
jeffrey richter:嗯,绝对如此。良好的编程典范规定:当编写一个函数时,必须验证所有传递进来的参数,如果任何一个参数不合乎要求,就应当明确地引发一个异常,而在基类库中定义有大量的异常类,所以可以轻而易举地使用其中的一个。但是您同样也有能力定义自己的异常类,或许,要查找数据库中的、顾客(customer),却好象没有发现他们的名字,故可以创建自己的customer异常,并在代码里的某个地方引发它。
robert hess:或许会用类似customer的名字作为损坏的customer名……
jeffrey richter:是的,大概这样。如果它是"robert",就是你一直想要引发的异常。
robert hess:那么,您认为c#作为一种编程语言将如何发展?当您的客户参加培训时您对他们有什么点拨,他们对此又有什么想法?
jeffrey richter:嗯,我真的认为它将获得巨大的动力。我说过,去年我一直专门用c#编程,偶尔也用c++,但现在却很少用了,而我相信许多vb程序员也将会转向此语言,因为c#更适合公共语言运行库。所以,我真的认为它将获得巨大的动力,并且真正得到重用。在我的培训班里,似乎每个人都喜欢它,事实上一些人说他们参加这个培训班,只是由于这个班开设了c#编程的课,但很快他们就高兴地发现课程也涵盖了framework和类库。
robert hess:那么,当谈到.net framework和类库时,您认为它们怎么样,以及它们是怎样帮助应用程序开发的?
jeffrey richter:我认为,这个平台表现很出色。我使用整个平台已经一年了,并且我最近一直在为微软开发一个项目,以展示微软的许多技术。我和另外一个家伙一起工作,他的名字叫tom,我们要在早上碰头,要在电子白板上继续讨论,接着要…… 这里就是我们今天将要补充说明的性能,我们又要讨论一会儿,我们要表示,这就是当天结束时我们的目标,通常在午饭之前我们要全部完工。我们总是超额地完成了任务。
robert hess:您认为c#和.net的结合有助于完成工作吗?
jeffrey richter: 噢,当然。毫无疑问,因为所有的测试都已完成。所有的测试——我们如何公开这个东西,我们能不能使这成为一个方法,能不能把它放在dll里,能不能使其成变com 对象,我们应拥有什么类型的接口。所有的这些问题涉及到您如何把这些连接起来并传递指针,保持连接以便可以同步,所以您就可以通过保持和其他人同步来通知他们,所有这些论点都刚刚被引进该平台。因此,自始至终地,我们愿意工作一个小时,我们要完成某项工作,我们会……,然后我们又要坐回去并开始增加其它的东西。我们的生产率如何,确实令人难于置信,而且也同样充满着乐趣。我们确实增加了惊人的图形图像库和alpha混色(blending)以及所有类型的东西,这些以前我们从未处理过alpha混色此类东西。我曾经从事过图形图像的工作,但已经过了好多年了。而利用相应名字空间中的system.drawing语句,我们就能够构造这些图像并对它们进行覆盖和alpha混色,然后又从我们的web服务器返回这些图像给在任何机器上运行的任一客户,甚至不必是一台windows机器。
robert hess:我想这带来了有利的选择。迄今为止,我们一直在谈论用c#和.net framework等进行应用程序的开发,并且我了解到您原来就是一个货真价实的应用程序设计师,编写windows应用程序和标准的gui程序。令人意外的是web出现了,因此每个人都想到编写web应用程序,或编写运行在浏览器内部基于html的应用程序。但现在以一句话对您的产品进行概括,您正在谈到具有这种alpha合成标准的windows图形应用程序,也谈到了访问web并以相应的格式返回给其它系统。那么象您我这样的win32应用程序开发者,对传统的应用程序开发环境以及新的web应用程序与.net的混合有什么看法?
jeffrey richter:嗯,我实际上在做的就是这种特别的事情,它不是win32图形应用程序,而是一个web窗体(form),随意一个web窗体。
robert hess:那么它甚至也不是一个传统的windows应用程序吗?它听起来很象啊。
jeffrey richter:嗯,它真正是什么?实际上它比传统的win32程序具有更复杂的体系。它实际是一个web服务,并且我认为它是第一批公用微软web服务(public microsoft web services)之一,是免费的,所以我会给出url地址。因此谁都可到那里去摆弄摆弄,这个地址是teraserver.microsoft.net。
robert hess:噢,我会把这个地址放在本记录稿的后面,以便大家点击访问。
jeffrey richter:那里有许多微软技术的广告宣传,其中包括windows 2000 datacenter、sql 2000、iis、asp.net、.net frameworks、web services和web forms。所在的资料都在那个网站上。有一个具有图像信息的teraserver web服务,它显示立体地形图和常规像片里的图像和标题。而且我们也有一个人口普查(census)服务,所以可以到那里输入纬度、经度等,便得到相应的城市名以及生活在该地区的人口。我们还有地标(landmark)服务,给出一个以经纬度标定的矩形区,就可以找到该地区范围内的医院和学校。因此,它们是三个单独的web 服务。它们本来可以由不同的公司实现,但实际上都是由我们实现的。接着我们编写了一个web窗体应用程序,它本来可以由任何公司编写,但这次又由我们编写,以便弄清概念,它向这三个不同的web服务发出信息,接着从teraserver获取标题信息,从landmark服务器获取地标信息,然后我们就能够把这些信息载入地图。
robert hess:使用alpha混色。
jeffrey richter:嗯,对,使用alpha混色。于是,这些信息被送回web窗体,送回运行在任何机器上的客户。我们甚至可以增加这样的功能,当鼠标移到某东西上方时,提示工具将会显现并告诉您该网页上相应的学校名和医院名。此范例功能之强大,简直令人无法相信。事实上客户可以是运行任何操作系统的任何机器,并且我们在服务器端利用windows 2000的gdi+性能处理alpha混色,以及此类高级图形操作,不过我们只把位图(bit map)送回给客户,我再次认为,其功能之强大、生产率之高,简直令人信难于置信。而且我也了解到许多应用正在朝这个方向发展。
robert hess:所以您真的很喜欢web应用程序的整个web模型。
jeffrey richter: 喜欢。
robert hess:即使您是一个传统的windows应用程序开发者。
jeffrey richter: 是的。
robert hess:您现在已横下心来要朝这个方向发展了。
jeffrey richter:是的,我已下决心了。程序要能在任何地方运行,并在服务器上进行工作。所有的这些便构成了所谓的分布式系统(distributedness),服务器可以位于三台不同的机器,噢,维护所有的这些资料的sql server还可以是另一台机器,web 窗体服务器也位于不同的机器,并且还可以被不同的公司细调以便随意使用这些材料,他们觉得这些材料适合于生成内容丰富的应用程序,而这些程序运行在能被inte.net访问到的任何地方。这简直令人难于置信,确实难于置信!
robert hess:某些迹象告诉我,所有的这些东西给您留下了现象。
jeffrey richter:是的,有点。
robert hess:那么,对于观众中跃跃欲试的开发人员,他们想要投身于c#,并要开始编写一些.net应用程序,在他们跨出第一步之前,需要真正地了解什么?您认为最后还有什么要强调的?
jeffrey richter:我认为,这些开发人员即将面临的一个最大问题就是,他们必须认识到是c#语言揭示了runtime和基类库中的性能,或许假以时日他们会从经验中学到。而许多人将会关注c#,也可能他们会试一试,或关注其它的.net语言,也有可能会企图做一些不被这些语言所支持的事,接着当然认为这是不可能的。例如:在c#中,所有的数组默认都是基于0的,是以0索引(下标)开始的。但是公共语言运行库支持数组有任何的下边界和上边界。在基类库中构造了一个数组,它具有所设定的上下边界。但是c#自然不提供这些功能。因此,您必须去学习,随着时间的推移,就会了解它是什么,很多时候您或许可以使用其它语言,或者去访问语言的底层系统,语言是位于runtime顶端的,由于某些原因,设计者不让我们去访问底层系统。
robert hess:似乎就是这样,通过理解runtime底层的所有性能,然后您就可以把这些性能映射(map)给您目前正在使用的任何语言,以便了解它们是否提供给您所需要的功能。例如,我写网页时总是用纯粹的html编写,因为我知道它的具体功能是什么。但是假如我必须用frontpage写,我知道frontpage有它自己的格式(mindset),关系到网页的显示,并且我知道它能给我提供什么,不能提供什么。偶尔我也不得不转回纯粹的html并按这种方式增加某些东西或其它工具,这似乎是同样的事情。
jeffrey richter:有时在c#中也有这些功能,但却以不同的名字出现,例如,在公式语言库中,虚拟函数被称为family 。于是要在c#中创建一个虚拟函数,就会用protected 限定。对,或不用protected,但是在c#中的protected是等价于公共语言运行库中的family的。噢,搞混了。看看,连我自己也糊涂了。
robert hess:因此基本的思路听起来好象就是要去理解您正在使用的工具,以及它们在.net framework底层的运行情况。好了,非常感谢jeffery,又与您交谈我感到非常荣幸,以后我会找一个时间再次邀请您回来参加这个“show”节目的。
jeffrey richter:好,我很乐意,谢谢。
robert hess:这就是程序员jeffery对c#和.net framework的看法。他提供给你们一些好资料,以让你们了解更新的开发领域。他讲到了很多的url地址和源代码例子以及类似的资料。我保证把它们放在本记录稿的后面,所以请继续观看其余的“show”节目,看看还有什么内容。
……(略去与c#无关的谈话)
结束语
robert hess:谢谢您参加另一期的msdn show。这一次我们讨论了用c#编程的问题。
erica wiechers:在下一期的msdn show节目里,我们将谈论soap以及它是如何被整合到.net编程体系的。
robert hess: 到那时,我们再在网上见面。
更多资料的链接
microsoft c#资料:
c#综述和介绍(overview and introduction to c#,http://msdn.microsoft.com/vstudio/nextgen/technology/csharpintro.asp)
c#语言规范(c# language specification,http://spectre/test/library/default.asp?url=/library/do.net/csspec/vclrfcsharpspec_start.htm)
msdn之声:深入c#专栏(msdn voices: deep c# column,http://msdn.microsoft.com/voices/deepc.asp)
一个定期的专栏,在这里bobby schmidt分享他使用c#的观点和见识。
msdn .net开发者中心(msdn developer center for .net,http://msdn.microsoft.com.net/)
提供更多有关.net技术的开发资料。
c#新闻组(c# newsgroup,news://msnews.microsoft.com/microsoft.public.do.net.languages.csharp)
与正在学习使用c#的人互相讨论、互相请教。
有关jeffrey richter谈话的资料:
代码范例(sample code:地址不详)
书: programming applications for microsoft windows
programming server-side applications for windows
(和jason clark合写)
wintellect(http://www.wintellect.com/,)
jeffrey 的培训和咨询公司。
terraserver.net(http://terraserver.microsoft.net/)
jeffrey帮助编写的mapping服务。
jeffrey richter的主页(http://www.jeffreyrichter.com/)
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器