怪怪 | Nothing, Everything

"有过一个发疯的时刻,有感觉的钢琴以为它是世界上仅有的一架钢琴,宇宙的全部和谐都发生在它身上." - 狄德罗
随笔 - 101, 文章 - 3, 评论 - 1996, 引用 - 42
数据加载中……

煽风点火:也论Bjarne Stroustrup的"基于对象"的含义, 同时B4一下大师

这篇文章在我看过原文之后,  确认是一种误解, 当个消遣看的话, 里面还有点东西, 不过价值不大, 切不可当真! 理解本文的关键是, 确认其中"编译时刻确定"所包含的内容:

本文中"编译时刻确定", 包括了对象创建逻辑的确定. 根据Bjarne Stroustrup原文上下文理解, 则不包括对象创建逻辑的确定.
 
如果谁在之前看过这篇文章, 造成了误解, 我在这里做一个真诚的道歉, 并保证这是我唯一一篇如此不谨慎的文章; 以后我是宁可不写也不能造成误导, 作为一个博客园的新作者, 这给我上了很关键的一课, 也请后来人引以为鉴. 关于大师原文的意思, 请参考我当天的第二篇文章:


反弹和补遗:再论Bjarne Stroustrup的"基于对象"的含义

上面文章中的另一种解释, 理解上和大师的原意不会有太多偏差, 其中涉及到本文的部分, 可以跳过, 其它部分请放心阅读和讨论.

以下是文章原来的部分.

在The C++ Programming Language 3rd (Bjarne Stroustrup, 1997)里:
第9页:
Objects of some user-defined types contain type information.
Such objects can be used conveniently and safely in contexts in which their type cannot be deter-mined at compile time. Programs using objects of such types are often called object based.

一些用户定义类型的对象包含了类型信息(前因)。
这些对象可以便利和安全的应用于上下文,它们的类型不能在编译时被决定(后果)。程序对这些类型的对象的使用经常被叫做基于对象。

说实话,翻译的比较蹩脚,因为大师的英文真的不那么深入浅出。不过要说的是,很多人的翻译和理解是绝对错误的,包括deerchao把compile time误认为是run time, 同时把determined翻译成了分辨; 也包括徐少侠对这一段话的理解。这段话的前提首先要搞清楚: C++是一门静态面向对象语言,所以基本不存在什么运行时决定类型的问题. 很自然的矛盾就指向于: 对象的类型是编译前就定死了, 或编译时确定之。搞清楚了矛盾在哪儿, deerchao就不必放弃这句话作为他的论点基础了, 因为deerchao原贴基本上就是围绕这句话展开的, 自然弹药也就充足了.

接下来详细说明。

Object o;
if(情况A) {
    o= new Book();
}
if(情况B) {
    o = new Dog();

}
o.ToString();

以上流程中,变量o所指代的对象的实际类型是在编译时被决定的。这个对象的实际类型在情况A下是Book,然后再另一种情况下则是Dog.

Book b;
if(情况A) {
    b = new TextBook();
}
if(情况B) {
    b = new GraphBook();
}
b.Open();
b.DoSomething();
以上流程同理。

b的类型被限制为基类Book(通过定义时Book这个类型信息),但它所指代的对象的实际类型具体是TextBook还是GraphBook,虽然在这个流程中有所变化,但这些变化都在编译时刻决定(就决定—相对于动态语言或某些后面说到的做法,才决定—相对于用户声明直接把类型限制死),编译的结果中就包含着创建不同实际类型的这一被指代对象的逻辑或信息。同时,由于b被声明为Book, 假设b是public的,那么b所指代的那个对象的实际类型到底是什么,也被限定为Book的子类。如果有另外一个新的模块(比如另外一个DLL)含有跟创建该相关的流程,调用了这个b,并给这个b赋值,这个过程是在新模块的编译中被确定的,同时也就确认了变量b所指代的对象在流程中实际类型

很显然对于Book b这样的做法使得b所指代的对象在编译时, 其实际类型可以是不固定的(但按照静态语言本身的能力来说,不能在被编译之后的其它过程中才固定),由编译的结果来确定在这种情况下是什么,在那种情况下是什么。这叫做编译时刻确定. 但是如果TextBook b, 假设TextBook是继承链上的最后一个类,那么其实际类型由于被声明定死不能改变, 也就是说不具有推后到任何一个编译过程中去确定类型的能力,这叫做不能在编译时刻确定。而我们经常用的拥抱变化的手段之一,就是把b所指代的对象的实际类型的决定,放到其它单独编译的模块里去,让其它编译结果决定我们现在写的程序的对象的实际类型。

那么关于运行时确定类型这种误解来自于哪里呢? 关键在于以下具体做法的流行:

模块一:
Book b = BookFactory.Instance.Create(最终用户决定的参数);
b.Open();
b.DoSomthing();

public class BookFatory {
    public static BookFatory Instance {
        return (BookFactory)根据配置文件获得的实例.       //注意: 不是编译时确定, 而是运行时确定, 后面解释!
    } 

    public abstract Book Create(String param);
}


模块二:
public 某特殊BookFactory : BookFactory  {
    public override Book Create(String param) {
       switch(param) {
            case "参数A":
                return new TextBook();
             case "参数B":
                return new GraphBook();
             default:
                return new DefaultBook();
        }
    }
}

模块二中关于返回的对象到底是什么类型的, 是编译时刻确定的. 但是对于模块一, 有一个和我所说的冲突的地方(BookFactory的具体类型的确定), 也是为什么很多人理解为运行时刻改变类型的原因. 只所以出现这种误解, 是因为混淆了Activitor.CreateInstance(Type type)这类工具箱和语言的界限造成的. 对于C++和C#这类静态面向对象语言来说, 它本质上不具有在运行时刻改变类型的能力. 它还缺乏一些其它的能力, 所以我们需要Activitor和反射这些东西来帮助我们. 但在大师讨论这个问题的时候, 并没有包含额外的非语言的能力的.

于是我们讨论时, 也要排除其它因素的干扰. 考虑如下代码:
第一种:
TextBook b;
if(情况A) {
    b = new TextBook();
    b.Open();
}
b.DoSomething();
if(情况B) {
    b = new GraphBook(); //不行
}

第二种:
TextBook b = BookFactory.Instance.Create(用户输入参数); //不行

为什么不行? 因为对象定义类型时, 包括了过多的类型信息啊! 这就是不能在编译时刻确定的本质含义: 大师说, 用户定义类型的对象(在这里由b指代)包含了类型信息(TextBook b)的用法, 相对于(Book b)这种b所指代的对象在某种情况下是TextBook在另外一种情况下是GraphBook在过程的编译时刻才确定(而非很多人想像的在执行过程中确定)的用法,  把前者叫做"基于对象".

deerchao对大师把握的本意并没有错, 问题是他因为最初的翻译错误, 轻易的把这一条放弃了. 但是我发现, 基于对第一条的错误理解, 大家的讨论向着一边倒不利于deerchao的方向发展; 出于搅风搅雨, 煽风点火的目的, 我在此澄清几点:

1. 静态语言不能够"运行时确定", 但是能"编译时确定"(是TextBook/GraphBook/TextBook或GraphBook,根据编译时获得信息不同而不同), 这是相对于用户声明"包含类型信息"(某特殊Book), 所以实际类型不能推迟到"编译时确定", 因为它已经在编译前就定死了.
2. 让deerchao和咱们走入误区(把compile time和run time混淆)的根本原因在哪里: 引入了静态面向对象语言本身并不包含的特性, 这也是很多框架通过提供工具去扩展静态语言的能力的方向之一.
3. 对于TextBook b而不是Book b的用法, 大师确实说"常常把它们叫做基于对象", 但是请大家注意, 这里有个"often".

接下来说一下徐少侠兄弟的言论:

"举例来说
Javascript不是面向对象的
虽然他里面的变量在运行时实质都是有类型的,但是在非运行时无法知道是什么类型
同理很多脚本语言都是这样的
因此由于在语言中支持对象的使用,但又有类似这样的缺陷,这些脚本语言被称为基于对象的语言"

这个纯粹是一个误解. 把静态面向对象语言和原装面向对象语言给等同了. 其实类似于Javascript的脚本语言, 现在在国内外已经被广泛的认识了. 还抱着不是静态面向对象语言就不是面向对象的看法来否认这些语言面向对象的特性甚至本质, 那可以说知识稍微有些过时. 恰恰相反, 现在更多的讨论是, 静态面向对象语言对面向对象的曲解, 和由于其自身限制, 对我们开发软件带来的麻烦. 向动态语言的优点靠拢, 也是Activitor, 反射, 甚至Emit这些手段风行的原因. 但决不能说, 不是静态的, 就不是面向对象的, 这哪怕跟20年前的面向对象原始概念, 也是不相符的.

同时由于这些语言可以做到在运行时刻才确定其类型, 不说其更多的好处, 仅只与"编译时刻才确定其类型(或类型的范围及该对象的创建逻辑)"相对应, 按照Bjarne Stroustrup的观念, 也绝不可能说他们是基于对象....

多说的一句其实不该说的话是, 徐少俠兄弟, 在我在博客园的几天的感觉, 说实话, 怎么说呢, 就像他自己说的, 一看就像"培训师".., 我觉得我这种感觉, 对我对"老师"的认知是不符的. 当老师就应该认真负责一些, 别人(比如我)可以大嘴, 你负责着很多人对知识的把握, 不太熟悉的不能想当然的就乱说啊.... 如果有误会,我在这里道歉先。

最后, B4一下Bjarne Stroustrup的语言表达能力, over.

posted on 2007-09-21 15:04 怪怪 阅读(1778) 评论(39)  编辑 收藏

评论

#1楼    回复  引用    

深刻。
2007-09-21 15:49 | kingren [未注册用户]

#2楼    回复  引用  查看    

Got no time to think into it at that moment, it was just like in a war :(
2007-09-21 15:59 | deerchao      

#3楼    回复  引用    

不错
2007-09-21 16:01 | SE [未注册用户]

#4楼    回复  引用  查看    

我已经被无数真正的高人一起打倒了,你就不必再点这把火了。。。

同时这两天确实见识到了高人们的真正水平,对自己的水平到底算是怎么回事心里更有把握了。
2007-09-21 16:04 | deerchao      

#5楼 [楼主]   回复  引用  查看    

@deerchao
哈哈哈, 偷偷的在回复里说一句, 由于大师的表达能力太差, 你那个帖子的回帖里有些人的话, 根本是任意曲解, 胡说八道. 我昨天就想帮你一把的, 但是现在是注册用户了, 不想得罪人; 但是琢磨了琢磨, 感觉还是良心更重要, 毕竟博客园的帖子会影响很多初学者的.
2007-09-21 16:09 | 怪怪      

#6楼    回复  引用  查看    

问个问题用来准备扔砖头?
C#算不算静态语言?

C#是否存在编译时不能确定类型的情况?
2007-09-21 16:42 | 徐少侠      

#7楼    回复  引用  查看    

至于JavaScript是不是基于对象
我以前是见多脚本强人的,本人也算半个。
强人就是说JavaScript完全能做到封装、继承
但是请把所谓的几个基本的OO思想都体现一下?很难的

2007-09-21 16:45 | 徐少侠      

#8楼 [楼主]   回复  引用  查看    

@徐少侠
呵呵,每个人不可能对所有的问题都了解。

如果你真打算拍死我,我相信你能做到。对我来说,能做到所谓知之为知之,不知为不知,就可以了。

正文中已经提到了静态语言中的一种在编译时不能确定类型的情况,就我所知简单的解释了一下。重构了一下正文,让结构更清晰,你不妨看看, 交流一下。
2007-09-21 16:46 | 怪怪      

#9楼    回复  引用  查看    

没仔细看你的源贴,抱歉了
不过找到一条话
引用:
对于C++和C#这类静态面向对象语言来说, 它本质上不具有在运行时刻改变类型的能力.

当然,我是一个讲师,因此很会了解很多人其实每天在做高难度的IT工作
但是却很可能对一些基本概念很模糊

现在我也不扔砖头
你自己写一段代码自己承认错误

请写一段DeerChao特别热爱的基于OO的多态样例

然后自己解释一下,是否编译器能完全做到在编译时就知道该到哪段二进制代码行去执行
就用C#好了
2007-09-21 16:51 | 徐少侠      

#10楼 [楼主]   回复  引用  查看    

C#是静态语言,但是通过Framework工具箱和其他手段扩展了动态的能力。

至于JavaScript体现封装/继承和更重要的多,我不敢算脚本强人(甚至不算半个),仅能算入门,但是已经能体会的到。

我觉得讨论不能给予这样的形式: 你单方面的提出问题,然后让别人证明你是错的(或对的), 然后你再提出另外一个问题,如此无穷无尽。 因为大家没有那么多时间为了讲解这些付出工作量和脑力。

毕竟,就像我常说的,谁也没给咨询费不是?
2007-09-21 16:52 | 怪怪      

#11楼    回复  引用  查看    

@怪怪
如果没有运行时确定类型
就根本不可能有多态
如果园子里都没有这个认识?
到真的需要好好辩一辩

这里有谁写过多态的代码?
写过的来评评理,能不能编译时确定?

再往深入将,究竟为什么如今流行的动态语言要叫动态语言?

大家小心啊,两个动态的意思不一样的。
2007-09-21 16:58 | 徐少侠      

#12楼    回复  引用  查看    

@徐少侠
他不是这个意思,他的意思是说如果你定义了一个
Car car1;

那么运行时car1是绝对不会指向一个Bird的实例。

至于指到的是FordCar,还是BMWCar,那么是正常的,因为这些都实现了Car类型的接口,也就是说可以认为他们是Car,即car1的静态声明类型。
2007-09-21 17:01 | deerchao      

#13楼 [楼主]   回复  引用  查看    

@徐少侠
如何运行时刻改变,我文中一提到一种方法。但我说的很清楚了,这不是语言的能力。而是框架/工具箱等其它手段提供的。如果只有一个最基本的C# 1.0的编译器,我倒想问问你如何做到呢? 提问题也不能总是单方面吧...

"当然,我是一个讲师,因此很会了解很多人其实每天在做高难度的IT工作
但是却很可能对一些基本概念很模糊"

这样的话最好不要多说,对辩论本身和真理都没有益处。就事论事,那个概念模糊,你个人是怎么理解这个概念的,拿出来讨论便是。
2007-09-21 17:04 | 怪怪      

#14楼    回复  引用  查看    

动态,静态,强类型,弱类型这几个词容易混淆,在Javaeye上有个很好的贴子说得比较清楚(http://www.javaeye.com/topic/35763):

关于静态动态,强类型和弱类型,推荐看看:Dave Into Python一书:
摘要如下:

静态类型定义语言
一种在编译期间数据类型固定的语言。大多数静态类型定义语言是通过要求在使用所有变量之前声明它们的数据类型来保证这一点的。 Java 和 C 是静态类型定义语言。

动态类型定义语言
一种在运行期间才去确定数据类型的语言, 与静态类型定义相反。 VBScript 和 Python 是动态类型定义的, 因为它们确定一个变量的类型是在您第一次给它赋值的时候。

强类型定义语言
一种总是强制类型定义的语言。 Java 和 Python 是强制类型定义的。您有一个整数, 如果不明确地进行转换 , 不能将把它当成一个字符串。

弱类型定义语言
一种类型可以被忽略的语言, 与强类型定义相反。 VBScript 是弱类型定义的。在 VBScript 中, 您可以将字符串 '12' 和整数 3 进行连接得到字符串'123', 然后可以把它看成整数 123 , 所有这些都不需要任何的显示转换。
2007-09-21 17:05 | deerchao      

#15楼    回复  引用  查看    



?在争论什么?

c++ 是静态类型语言。所谓静态是指类型,而不是对象。也就是c++不能修改类型,不能增加类型,不能删除类型,在运行时。但是可以修改对象,修改对象与对象之间的结构之类的。

c# 可以通过.net框架来支持增加类型,修改类型。但是语言本身,确实没有这个功能。但是现在c#也慢慢修改了,增加动态语言的功能也是假以时日的事情。


2007-09-21 17:06 | 航天奇侠      

#16楼 [楼主]   回复  引用  查看    

@徐少侠
呵呵,那你就提些运行时确定的例子,咱们就你说的例子展开讨论吧。

不过提醒一下,我不是一个培训师,靠做东西吃饭,声誉对我不重要,所以我出错的代价要小很多; 而且我的习惯是,一个辩论一旦开始,就不会再给任何人留面子(包括我自己)。

所以你的论点/论据/论证请谨慎一些。 至于单方面的你问我答,恕不参与,理由上面已经陈述过了。
2007-09-21 17:09 | 怪怪      

#17楼 [楼主]   回复  引用  查看    

@deerchao
这个很及时,Thank you.
2007-09-21 17:11 | 怪怪      

#18楼    回复  引用  查看    

最后的感觉

人家大师的意思是说
在编译时无法通过上下文来确定这些对象的类型
那么这种程序叫做基于对象的

另外,传统上我们往往仅将语言区分成完全支持面向对象的,和仅仅基于对象的或者不面向对象的。

不会就某段程序这么说。deerchao既然有这么个想法,附和一下讨论点思路也好。

还有,你的帖子里还有混淆变量和对象的问题
只能说你偷换概念了,说你不懂肯定生气地
以后你记住,任何对象,不是变量哦,对象的类型是永远不可能改变的。
你能让一只猫变成狗吗?
如果能,那么看看改变的究竟是对象本身,还是一个变量

另外,你的帖子其实也非常混乱
你说的:
C++是一门静态面向对象语言,所以基本不存在什么运行时决定类型的问题.
什么叫基本不存在?
因为也是你说的:
对象的类型是编译前就定死了, 或编译时确定之
如果连你自己都不肯定C++的对象是不是绝对编译时确定或不确定
那么你后面的长篇推论又有什么意思呢?

我觉得问题关键是,我们把基于对象这个标签
贴到某个语言上合适
还是贴到某段代码上合适


2007-09-21 17:13 | 徐少侠      

#19楼    回复  引用  查看    

--引用--------------------------------------------------
怪怪: @徐少侠
呵呵,那你就提些运行时确定的例子,咱们就你说的例子展开讨论吧。

不过提醒一下,我不是一个培训师,靠做东西吃饭,声誉对我不重要,所以我出错的代价要小很多; 而且我的习惯是,一个辩论一旦开始,就不会再给任何人留面子(包括我自己)。

所以你的论点/论据/论证请谨慎一些。 至于单方面的你问我答,恕不参与,理由上面已经陈述过了。
--------------------------------------------------------
那先搞清楚是不是真的有分歧要辩论,万一两个人的语言误会,那不开国际玩笑

我想证明虽然C#是个静态语言
但是C#存在变量的实际类型只能在运行时确定,编译时是不可能通过程序上下文推断实际类型的。
如果你觉得这是可能的,我就不用证明拉,因为咱没分歧,可能是有些误会。
2007-09-21 17:22 | 徐少侠      

#20楼 [楼主]   回复  引用  查看    

@徐少侠
我写那句话时,是为了防止别人又把框架和工具箱的能力拿来混淆,后来文章扩展了,把语言单分了出来,就出了语病。

包括某变量对对象的指代和对象本身,这里确实没有划分清楚,但是我个人认为不影响论题。大师原来的话也极容易造成混淆,这并非是因为我或者大师为了偷换概念。当然了就像我常说的,大多数人敢任意评价身边的网友,但不敢随便评论国外的大师。

挑别人的细节错误对讨论没什么意义, 能理解到对方的意思就可以了。至于谁概念不清楚这种问题,也不是我所关心的,让别人去判断吧...。 既然是误会,那就鸣金收兵好了,煽风点火没成,失败 :(。

:)
2007-09-21 17:26 | 怪怪      

#21楼 [楼主]   回复  引用  查看    

我重新编辑一下原文,谁还想拍我,我给你们留几分钟时间截个屏...
2007-09-21 17:28 | 怪怪      

#22楼    回复  引用  查看    

@徐少侠
@怪怪

就这么散了啊,我当回观众容易么?
2007-09-21 17:29 | deerchao      

#23楼    回复  引用  查看    

赫赫
本质如果每分歧吵什么啊

可能我没看仔细他的文章。
除非过阵子我上面那个确认贴说的东西除了怪怪还有人不同意,那真的要去踢馆的

我想证明虽然C#是个静态语言
但是C#存在变量的实际类型只能在运行时确定,编译时是不可能通过程序上下文推断实际类型的。

另外有弟兄说C#是靠框架支持的
那么我就写一个什么都不using的代码出来,只用
class、new、赋值运算、继承、虚方法
这些都不需要框架支持吧?
其实说这个问题的人都把OO里面多态的动态决策和动态语言的动态搞到一起去了
C#是静态语言,但OO必须要求语言有运行时动态决策的能力。否则该语言就不是OO的语言
2007-09-21 17:44 | 徐少侠      

#24楼 [楼主]   回复  引用  查看    

现在看还有问题么?

@deerchao
等着你开火呢.. :)
2007-09-21 17:51 | 怪怪      

#25楼    回复  引用  查看    

@怪怪
我可没时间和精力再来了,昨天论战一天,被人批得体无完肤,今天刚刚重装系统,正在装软件。
这两天就在一事无成中过去了。。
2007-09-21 17:54 | deerchao      

#26楼 [楼主]   回复  引用  查看    

@deerchao
我本来以为这个问题解决了,你就可以继续了...
2007-09-21 17:59 | 怪怪      

#27楼    回复  引用    

@徐少侠

很想见识一下这个程序 :)
2007-09-21 18:02 | fc [未注册用户]

#28楼    回复  引用  查看    

@怪怪
反正论来论去我还是觉得我是对的,别人也觉得他是对的,谁也改变不了谁,没什么意义了。
2007-09-21 18:03 | deerchao      

#29楼    回复  引用  查看    

引用怪怪:
我在此澄清几点:

1. 静态语言不能够"运行时确定"

我还是有不同意见阿?
我想证明虽然C#是个静态语言
但是C#存在变量的实际类型只能在运行时确定,编译时是不可能通过程序上下文推断实际类型的。

算不算咱们有分歧的地方啊?
一句话:静态语言不能够"运行时确定"变量所指代的类型?
2007-09-21 18:04 | 徐少侠      

#30楼 [楼主]   回复  引用  查看    

@徐少侠
这个是因为,我把对象创建逻辑所造成的实际类型变化,看作编译器把它们定死了;而你关注的是,既然创建的对象实际类型不同, 你就认为变量所指代的对象其类型可以变化(其实是在某一范围变化)。

显然大师说他那句话时,指的是我这个意思,我这篇文章就是澄清这一点的。
2007-09-21 18:13 | 怪怪      

#31楼    回复  引用  查看    

假设TextBook是继承链上的最后一个类,那么其实际类型由于被声明定死不能改变, 也就是说不具有推后到任何一个编译过程中去确定类型的能力,这叫做不能在编译时刻确定。

你唯一提到不能编译时决定的就是这个话了

具体说说看
你对所为不能编译时确定的实际理解?
2007-09-21 18:26 | 徐少侠      

#32楼    回复  引用  查看    

所以我们需要Activitor和反射这些东西来帮助我们. 但在大师讨论这个问题的时候, 并没有包含额外的非语言的能力的.

是不是你暗示,如果不用工厂模式那么是不是就不可能做到运行时决定了?
2007-09-21 18:27 | 徐少侠      

#33楼 [楼主]   回复  引用  查看    

@徐少侠
工厂模式我估计不是唯一的手段,但是只要运行时决定,就要借助语言之外的手段。

我的理解是: TextBook b 使得无论是b还是b所指代的对象,都局限在TextBook这个类型上。

但如果TextBook又有子类则不同,比如现在往系统中新添加些类,如:
ColorTextBook : TextBook, BlueTextBook : ColorBook, RedTextBook : ColorTextBook。 而且同时添加了创建具体哪个类型的逻辑。那么在编译时,就确定了TextBook b所指代的对象可以是如上类型。
2007-09-21 18:38 | 怪怪      

#34楼    回复  引用  查看    

我觉得编译时确定“类型”这里的类型和class应该不是一回事,应该是指支持某一套操作/接口,是讨论Is A, Has A时的“类型”的定义。
2007-09-21 18:42 | deerchao      

#35楼    回复  引用  查看    

恩,分歧出来了

借助语言外部的手段?

好的,你后面的论述我还是同意的
TextBook有子类,因此类型为TextBook的变量b就可以指代所有直接或间接以TextBook为父类的对象

不过周末了,休息。

下周一继续
呵呵
那么我就写一个什么都不using的代码出来,只用
class、new、void、赋值运算、继承、虚方法
这些都不算框架支持吧?


2007-09-21 18:44 | 徐少侠      

#36楼    回复  引用  查看    

这折腾来折腾去的,很让人回想起学生时代,大家都是童心未泯啊
javaeye上的讨论基本能作为不少人的reference guide, best practice,这种讨论结果有什么用?
2007-09-21 19:00 | RicCC      

#37楼 [楼主]   回复  引用  查看    

@deerchao
严格的说不同,但是有了一些类才有了这些类型。

@RicCC
首先我说过Javaeye上的那些讨论,对最广大的程序员来说不具有真实意义,少数人搞就可以了。同时,我不认为Javaeye上的讨论能作为大多数人的指引,除非是指引到钻牛角尖的地方。

其次咱们这种讨论说实话都是些低级问题,正是因为低级问题很多初学者都弄错,所以这种讨论其结果才是最有用的,而且对大多数人有用。我过去也认为这些是没有用的,但是既然还有人会弄错,那么就有稍微搞一下的必要了。

2007-09-21 19:17 | 怪怪      

#38楼    回复  引用    

C++的泛型是编译时确定。
C#的泛型是运行时确定。

换句话说,C++的泛型的可能类型,受汇编指令的限制,在编译时就会遍历确定了。
而C#的泛型因为直接受IL指令的支持,可以到运行时再确定。

我不记得是在哪看的资料,但基本意思大概就是这样。
2007-09-21 21:33 | geniusleft [未注册用户]

#39楼    回复  引用  查看    

支持楼上的。
C#的泛型因为直接受IL指令的支持,可以到运行时再确定。

在C#用泛型时,生成dll后的代码并不是真正给机器执行的代码。执行从IL到机器码的编译以后才能算真正的编译结束(而该过程是有代码调整的)。
我想如果这样理解的话,那么C#是不支持动态类型操作的。因为反射等的动态获取类型其实还是在编译时(IL到机器码的过程)已经决定了,而不是最后在真正运行时获取。
2007-09-22 01:58 | 壁虎      

标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-09-28 07:33 编辑过


相关链接:
所属专题: 关于面向对象的讨论