only_lonely

今日之中國,必將為明日之笑柄
 
 

Powered by: 博客园
模板提供:沪江博客
博客园 | 首页 | 发新随笔 | 发新文章 | 联系 | 订阅订阅 | 管理

2010年3月29日

.net 一切都是对象

在.net中一切都是对象,这话你可能已经听了不下一百次.好吧,今天就再对你说第一百零一次吧

1,那个class

class 是类,class的实例是对象?  这话没错吧,绝对正确.但.. 请看下面的代码

class  A

{

     static Int32 a;

     Int32 b;

}

虽然没什么用,但的确可以定义这么一个类,OK?

 

接下来,有这样的一个代码片段

A a = new A(); //实例化一个A的对象

这段代码也是能执行的,现在有一个问题,在实例a中有什么?

一个Int32类型的字段b,

为什么没有那个Int32类型的字段a?

因为a是静态的,是属于类的,不是属于实例的

恭喜,全对~但还有一个小问题,那个a既然不属于实例,那它在内存中,存放在哪里呢?

随便找个地方~把a存放好,需要的时候,由编译器帮助我们找到它?

当然,这是可行的,可如果真这么做,那就太没有创意了

2 .net中一切都是对象

第一百零二次在你的耳边唠叨,就像一只邪恶的流氓兔,躲在墙角划圈圈... ...

在.net中 class 这个结构,本身也是由一个对象来表示的

用对象来表示类,这很重要

还是上面的代码

class  A

{

     static Int32 a;

     Int32 b;

}

A a = new A(); 

执行到这里之后,会有两个对像,两个实例,一个实例就是我们显而易见的a,那个包含了一份实例字段Int32 b 的实例,另一个是我们看不见的对象,我们暂且称呼它为 _A 吧,在_A里面包含了静态的字段 Int32 a

很明显的,类似_A的实例,只要存在一份就好,因为它只需要一份,来容纳那些静态的东西,

类似a这样的实例,是可以有无数个的

A a = new A() ; A b = new A(); A c = new A()…  只要你乐意,你可以实例化无数个实例

3 那个.cctor

在.net中提供了一种方法,让我们能够控制_A实例化要做的事情,那种方法就是.cctor

具体请参此文:

http://blog.csdn.net/only_lonely/archive/2010/03/11/5372171.aspx

posted @ 2010-03-29 18:54 only_lonely 阅读(8) 评论(0) 编辑
 

2010年3月23日

你好~未来!

昨夜的风,有些大,盖着厚厚的被子,仍然觉得有些寒冷,今天早上,懒洋洋地起床,洗脸,刷牙,上网查看邮件和新闻

 

  "Google 退出中国" 黑色的字体,赫然出现在眼前,微不可闻的一声叹息,终于还是走到这一步了,我不知道为何我会伤感,这样的结果早就是预料到的,可是真当它发生的时候,竟还有一些放不下

  我已经不忍心去看那些评论了,因为我知道一定有一批又一批的"群众"围攻,谩骂Google

  写到这,我想,我开始明白,我为何会伤心,我的伤心不是因为Google的离去,我的伤心是因为中国竟会有那么多人放下尊严像条狗般的狂吠

   也许正印证了我博客上的那句标题 -- "今日之中国,必将为明日之笑柄"

   话不多说,言尽于此... ....

   

    你好~未来!

    现在是公元二〇一〇年三月二十三日 上午九点三十分 我站在Google退出中国现场,为您报道.希望您能看到,明白我们的心情.如果中国还有未来的话...

posted @ 2010-03-23 09:28 only_lonely 阅读(7) 评论(0) 编辑
 

2010年3月22日

.net 值类型浅析

需要了解的

 

在以前的一篇博文中,浅析了.net如何识别引用的真实类型

传送门 : http://blog.csdn.net/only_lonely/archive/2010/03/11/5370787.aspx

本篇算是其的续篇,主要讨论有关值类型的一些事情

在此,我假设你已经了解有关值类型与引用类型的一些基本事实,为了方便说明,我在此它们罗列上来

 

1,值类型的实例被分配在栈中,引用类型的实例被分配在堆中(GC堆,或者其他的)

 

2值类型只能继承于ValueType,引用类型能继承于任何类型(除了ValueType)

 

如果你明白上面两点,而且清晰无任何疑惑,OK,你可以看下去

 

1,从一段代码开始

 

using System;

namespace only_lonely
{
    class Demo
    {
        static void Main()
        {
            Int32 i = 10;
            i.ToString();
        }
    }
}

 

翻看它的IL代码

 

.method private hidebysig static void  Main() cil managed
{
  .entrypoint
  // Code size       12 (0xc)
  .maxstack  1
  .locals init ([0] int32 i)
  IL_0000:  ldc.i4.s   10
  IL_0002:  stloc.0
  IL_0003:  ldloca.s   i
  IL_0005:  call       instance string [mscorlib]System.Int32::ToString()
  IL_000a:  pop
  IL_000b:  ret
} // end of method Demo::Main

 

嗯,很简单~ i.ToString() 在这里就类似 ToString(i),很简单的函数调用

 

接下来,改一下代码

 

using System;

namespace only_lonely
{
    class Demo
    {
        static void Main()
        {
            Int32 i = 10;
           i.GetType();
        }
    }
}

 

让我们DASM它

 

.method private hidebysig static void  Main() cil managed
{
  .entrypoint
  // Code size       16 (0x10)
  .maxstack  1
  .locals init ([0] int32 i)
  IL_0000:  ldc.i4.s   10
  IL_0002:  stloc.0
  IL_0003:  ldloc.0
  IL_0004:  box        [mscorlib]System.Int32
  IL_0009:  call       instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
  IL_000e:  pop
  IL_000f:  ret
} // end of method Demo::Main

它装箱了,不是吗?

 

现在只有一个问题,why? 为什么调用 Int32 类型实例 的ToString() 仅仅会成为一个简单的函数调用,而调用 GetType() 却会造成装箱

让我们回顾一下装箱的概念 装箱,把一个值类型变成引用类型

把 值类型 变成 引用类型   嗯,事情变得有意思了哦

回顾我最前面链接的博文

引用 = sizeof(void*)大小的对象头+所有属于实例的字段

而那对象头中,又存有能够准确识别真实类型的信息

 

你有联想到什么吗?

比如,值类型是不支持类型安全的(准确识别对象的类型),想要获得对象的实际类型,必须装箱(转换成引用类型)

 

现在,是时候重新认识一下我们的值类型了

在.net中

 

1,所有的值类型都继承于ValueType,ValueType又继承于Object类型

2,所有的值类型都是密闭的,无法被继承

 

以上两句,你是否觉得很熟习?

:-),只要不是<< XXX从入门到精通 >>之类的书籍,或多或少的,都会提到上述两句话

 

可是,你是否会对上面的2句话感觉到困惑?为什么值类型一定要是那样? .net强制规定的? 没错,可是.net为什么会这样规定呢?

OK,现在,我来换一种方式,把上面的2句话解释给你听

所有的值类型都是密闭的,无法被继承   -> 这意味着,值类型没有子类 (1)

所有的值类型都继承于ValueType,ValueType是引用类型 –> 所有的值类型都有一个引用类型的父类 (2)

在OO中,很重要的一点就是可以把子类隐式的转换为父类 –> 这是条件 (3)

(1) + (2) + (3) –> 值类型没有子类,所以不存在把一个值类型(子类)隐式转换成另一个值类型(父类)的情况(A)

如果要对一个值类型进行隐式的转换,只能把值类型(子类)隐式转换成ValueType(父类,确定了的引用类型) (B)

.net的类型安全,很重要的一个部分就是可以动态的识别类型的实际类型,并对它们进行转换 –> 这是条件(C)

(A)+(B)+(C) –> 当值类型要进行有关类型转换的类型安全操作的时候~必须被转换成引用类型 (至此,请返回本文首部,看一下那些代码)

 

再一次地,回顾我的一篇博文 http://blog.csdn.net/only_lonely/archive/2010/03/11/5370787.aspx

.net依靠的是引用前 (sizeof(void*)) 大小的特殊对象头进行动态的类型识别

而值类型没有那些,综合起来,你是否有想到点什么?

 

C++里面的"值类型"

大牛们说过,不能随便用c++去解释c#,但无奈~我的实力实在有限,只能牵强的附会一下~因此,本文~只当作一个可能错误的参考与假设~理解大概的意思就行 :-)

  在c++中并没有所谓"值类型"的概念,但有基本类型的概念

  何谓基本类型?就是编译器足够,完全了解的类型,像如下代码

  int a;

  int b;

  int c = a+b; // 等价于 c = Add(a,b);

是有重载操作符,使得两个int类型的数字通过符号"+"进行"加法"的运算操作吗?

没错,的确是的~,只不过那个"函数",编译器替我们做了

 

  让我们做一个更为大胆的假设,假如编译器替我们做的更多… …

 

int a = 100;

a.ToString(); //等价于 ToString(a);

当编译器看到以上的代码,自动的调用一个形如String ToString(int);的函数,并把a当做参数传递,这是能做到的!

 

注意:因为值类型是密闭的,继承于引用类型的,所以当它重载一个父类的方法时,并不需要考虑多态性,即使ToString()是重载了父类的方法,也并不需要多余的考虑,直接一个Call 函数调用就行

 

编译器不能做的事情

 

编译器是静态的,一次运行就OK的,它并不能提供对类型的动态的运行时类型安全保障 -- 那是CLR做的事情,所以``当需要准确的知道值类型的类型时,需要把它转换成引用类型,并让CLR进行分析…. …

 

 

 

 

 

posted @ 2010-03-22 20:13 only_lonely 阅读(16) 评论(0) 编辑
 

2010年3月17日

计算机简史(操作系统篇)

引言

在人类编写的软件里面,还没有哪一种,是如此的重要的,以至于其的出现,深刻的影响了整个程序界的走向,可以说,一个操作系统的进化史就能在很大程度的代表了程序世界的发展轨迹

本质上,操作系统与其他软件并无任何的区别,都是逻辑+数据,然后它是如此之重要,所以人们把它与其他软件分离开来

操作系统称呼为系统软件,其他基于操作系统的软件称呼为应用软件

然而这种划分,常常给初学者带来困惑与恐惧,使得他们不敢,不愿意用对待平常软件的平常心去对待它,这是很不好的

在正式开始之前

  无论你是否相信,所有的软件功能都是能够使用硬件实现的,就像是组装积木,硬件就像是简单的三角形,圆形木块,软件就是利用那些三角形,圆形拼成房子,汽车,拼成模拟的世界

   软件其实是一个过程,一个拼装积木的过程,那么如果有一天,你想要一个房子,而有人给你提供了一个房子形状的积木(硬件),那么拼装的过程(软件)就不再需要了

  软件存在的意义就在于,我们的技术有限,硬件无法提供一个完整的积木,只能使用软件,对那些零散的积木去进行拼装

  操作系统是一个软件,应用程序同样是软件,都是一种过程

  它们之间的关系,与高级语言中 语言 与 编译器 的关系类似

参考: http://blog.csdn.net/only_lonely/archive/2010/03/16/5386552.aspx

应用软件说 : 哥们,帮我跟硬盘说下,我要XXX文件 –> 与机器无关的,抽象的语意

操作系统对应用软件说 : 好的,您稍等 –> 与机器无关的,抽象的语意

操作系统对硬件说: 硬盘编号9527,把你的磁盘转动三圈半... ... –> 与机器有关的,具体的语意

当硬件操作完毕

操作系统对应用软件说 : "您要的文件在这里,请拿好" –> 与机器无关的,抽象的语意

事实就是如此简单

注意:

操作系统的核心就是抽象掉硬件的细节,为更高层软件服务,这才是它的精髓

所谓的进程,线程,内存管理,系统与应用软件分层,这些都只是操作系统为了更好的完成任务,而创造出的一种概念,一种行为方式

为了让你更好的明白,理解操作系统的核心,请你忽略,无视掉那些纷繁的概念,好的,现在,我们有一个操作系统,纯净的,不含一丝杂质的操作系统,没有进程,没有线程,没有那该死的内存管理,没有那该死的R3与R0之分,它唯一拥有的只是一个叫做 中断 的东西,好了~一切拖沓的铺垫都已经结束,让我们开始吧

一 操作系统是死的!

在很多人的眼睛里,操作系统是富有活力的,精力四射的,它无处不在,时刻运行,时刻准备为你提供服务

其实,这是一种错误的理解,要理解这种错误,需要从CPU的工作方式说起

就在不久之前,我们每台电脑上只有一个CPU,而每个CPU同一时刻内,只能做一件事情

你可以想象一下,当CPU正在处理你的应用程序的时候.操作系统怎么办呢?

答案很简单,操作系统的代码没有被运行,它就安静的躺在那里,像一具尸体

注意:操作系统并不是像很多人认为的那样,是一个无处不在的管家,它只在有需要的时候运行

操作系统只在需要的时候运行?

什么是需要的时候呢?

很简单,当应用程序或硬件呼叫它的时候,有一种被硬件支持的方式 "中断" 高效地实现了应用程序(硬件)调用操作系统(硬件)的服务

什么是中断? 百度一下,你就知道,如果你把它当成函数调用,我也不十分介意

http://baike.baidu.com/view/121718.htm

好的,现在我们有了一个尸体般的操作系统,当你调用它的时候,它为你服务,当你永远不调用它(这是可能的),它将永远不被执行,这就是最简单的操作系统(现在已经被淘汰,但历史上真的曾经存在),没有线程,没有进程,没有该死的内存管理,你看见了,只要你愿意,一切都可以如此简单

请看下面的一个简单代码

    while(true)

     {

          // do something bad

      }

在我们仅拥有的"纯净"操作系统中,这样的应用程序代码将会是一个灾难,你的机器将会陷入瘫痪,

毫无疑问,这样做是不好的~

而且有个特别有意思的地方,操作系统的发展可以简单的被认为,就是为了更好的解决上述代码所带来困扰

是的,没错!

   while(true)

     {

          // do something bad

      }

这是一段神奇的代码,操作系统的一次又一次的发展,进化,就是为了减缓,降低上面代码带来的杯具~

二 中断让尸体动起来

如前所述,操作系统就像尸体,你不去用中断去刺激它,它永远不会动一下

那如何让尸体(操作系统)动起来,像个正常的人一样?

很简单,不断的用中断,去刺激它就行,

感谢万能的计算机,让这个世界上,有一种中断叫时间中断

何谓时间中断?

就是每隔一个固定的时间,触发一个中断,打断CPU的执行序列,去执行操作系统的代码

嗯,现在好了~尸体已经动起来了

可是,一个动起来的尸体,有什么用呢?

让我们再来看一下那段神奇的代码

while(true)

     {

          // do something bad

    }

当你的计算机陷入到上述代码不能自拔的时候,操作系统有机会借由时间中断,抢夺过CPU的拥有权,从而使得它有机会终止那个错误的程序,或者安排另一个程序运行

安排另一个程序运行

我希望读者不要忽视这句话,安排是个动词,是一个人才能做到的事情,而不是一具尸体可以做到的,通过时间中断,尸体般的操作系统,做到了人才能做到的事情,这在医学上叫做什么呢? 借尸还魂?

这是问题的一个方面,另一个方面是 "另一个程序运行",嗯~有意思了哦,

做一个恶毒的假设,如果你的电脑在听音乐的时候不能看小说,在打字的时候,不能听音乐,在挂QQ的时候,无法浏览网页,你会想砸掉电脑,另买一个吗?(要是我,我会有那种冲动),CPU一个时刻只能运行一个程序,正是有了时间中断,快速的切换,才能够让我们的电脑看上去,好像能够同时运行多个程序

接下来的,要引出一个内存的概念

别害怕,这里要说的是一个最基本的内存的概念.

什么是内存,内存就是一个地方,存放着程序的代码,数据,让CPU去存取,操作

嗯,回到刚才的话题,时间中断制造出了多任务的假象,可以使得计算机好像是能同时运行多个程序

只有一个问题,那多个运行的程序,存放在哪里呢?

它们连同操作系统(操作系统也是个软件)存放在同一个内存里

让我们再看一下,那段悲情的代码

while(true)

     {

          // do something bad

    }

while(true)的问题,通过时间中断解决了,可是那句 do something bad 呢?

你知道的,连同操作系统在内的所有程序都存在内存里面

如果,那句 do something bad 恰巧把操作系统代码所在的内存中的内容给破坏掉

当下一个时间中断降临时,将会发生什么?

2012 ... ...

三 面包,有了~奶酪,也有了

如果,这个世界上,有某种东西,可以让每个应用程序之间独立运行,不受干扰,

如果,这个世界上,有某种东西,可以使得就算应用程序设计的再糟糕,再乱来,也无法破坏其他应用程序所拥有的内存

是的,那不是幻想,是真实存在那种东西,那种东西是一系列技术的集合,笼统的我们把它叫做虚拟内存技术.

嗯,面包有了,奶酪也有了,一瞬间,世界变的美好起来了,不是吗?

有关于虚拟内存技术的实现细节,拜托,如果要说,那可以再写5000字

有兴趣的童鞋,可以baidu或者google

值得一提的事是,从虚拟内存地址到真实内存地址的映射,是由硬件提供的~

抽象硬件,给应用程序更好的接口,这本是操作系统的责任,现在却由硬件完成,这再一次证明了,硬件与软件之间,没有明显的界限

出于娱乐的目的,我们再看一下,那段神奇的代码

while(true)

     {

          // do something bad

    }

你可以在do something bad 中任意加上你认为足够胡闹的代码,然后测试一下,看它能不能干掉你的操作系统

四 一点声明

本文并不是严谨的论文,仅仅是从一个方面,粗浅的讲述了一下操作系统的发展历程,本文没有涉及到的内容,概念有很多,但是,只要把握操作系统的核心--"抽象硬件,为应用程序提供更方便的接口",从这里出发,不要心怀畏惧,一切都会很简单 :-)

五 windows下的一个小例子

  当按下键盘上A键时,键盘(硬件)触发一个中断,操作系统运行,检索出是哪个键按下,然后把按键信息发送到当前激活的窗口的消息循环,然后,当该程序运行的时候(时间中断),从消息循环中取出消息,识别,而后处理... ... :-)

 

only_lonely 原创,欢迎转载,请务必注明出处

拍砖您随意,只要有理,我一定心怀感激的虚心接受

posted @ 2010-03-17 22:32 only_lonely 阅读(78) 评论(0) 编辑
 

2010年3月16日

计算机简史(语言篇)

1 第一天,计算机诞生了

  计算机刚诞生的那会儿,是没有C#,C++,C等高级语言的,甚至没有汇编,CPU所唯一能够理解的就是一连串的二进制流,类似如下

   10010100010100101

   10011001101101011

这就是最原始的"程序",其中1表示高电平(或者其他类似的东西),0表示低电平(或者其他类似的东西),CPU能读懂它,并相应的执行一些最原始,最基本如 进位 的操作,至于CPU是如何实现这种操作的,那属于电气工程师的范围,我们的程序员之旅,就以此做为出发点

  直到现在,CPU所能够唯一理解的仍是一连串的二进制流

  至于为什么,那已经不属于软件的范围

2 第二天,程序员说,二进制太麻烦了,于是世界上便有了汇编

   随着光阴的流逝,越来越多的人参与了为计算机编写运行逻辑的工作(编程),越来越多的人觉得记住那些生涩的0和1是一项令人纠结的工作,于是``这个世界上便有了汇编语言

   基本上,汇编语言命令与二进制是一一对应的,他们联系十分紧密

   例如函数调用的 call 指令,对应着二进制的 01010110100 (这个数字是我乱写的``只为举例)

   这个时候,编译器也第一次出现了

   何谓编译器? 那时编译器就是 把 汇编指令转换为对应二进制流的小工具 

  值得提出的是,汇编语言,是不能夸平台的,不能在不同架构的CPU上运行

  CPU的架构? 就是不同的CPU能够识别的二进制流,一般的,不同架构的CPU能够识别的二进制流是不一样的

第三天,程序员说,我们要跨平台,于是高级语言出现了

汇编对于二进制的流好处是,把令人崩溃的0和1转换成了简单好记的英文字符

汇编有一个最大的缺陷,就是无法跨越平台,因为通常汇编命令与二进制的流有紧密的对应关系

很可能在A CPU 上进位的指令是 000000001 (数字是乱写的)

而在B CPU上进位的指令是 111111111(数字也是乱写的)

那么为A CPU编写的汇编程序,无法在B上运行,即使有源代码也不行,因为汇编与二进制的联系太过紧密,给人灵活的空间太少

于是高级语言便诞生了,其中影响最大的莫过于C

高级语言最大的贡献,莫过于抽象了完成任务的方式

在以前,用汇编语言,我们的思维方式是 用XXX指令把XXX数值放在地址为XXX的内存上

现在在高级语言中,我们的思维方式是 声明一个变量,然后给它赋值

高级语言的工作方式,更像是一个简明,高效的指导手册,它告诉你该如何去做,只要你达到目的就行,无论你是如何实现的

注意:直到现在,CPU所唯一能理解只有二进制的流,也就是说CPU并不理解所谓的高级语言,也不能运行那些高级语言

那高级语言是如何使CPU运作起来的呢? 很简单,把它转换成二进制的流

前面说过,高级语言就像是一本指导手册,告诉你该如何去做,却不管你是如何实现,而使用这本指导手册的就是编译器,正是从这个时期开始,编译器变得越来越重要,越来越,嗯~ 变态~

高级语言说 定义一个变量,然后给它赋值 –> 这个语意是与机器无关的

编译器听从它的指示,如果是要为A CPU 产生程序,它就用A所能识别的汇编指令编写指令

使用 XXX 指令把XXXX赋值给XXXX地址上的内存 –> 这个语意是与机器有关的

如果是要为B CPU产生程序,它就用B所能识别的汇编指令编写指令

使用 XXX指令把XXXX赋值给XXXX地址上的内存 –> 这个语意是与机器有关的

注意:由于汇编与二进制的流的联系是如此的紧密,所以便把它们当成是同一个对象,下文出现的也是如此

第3.1天 C只是高级语言之一

   对于许多程序员而言,从一开始进入这个领域,都是与C家族结缘,甚至一辈子,都在使用C家族的语言,这没什么大不了,C语言足够优秀,但有时,这也会阻碍我们看世界的眼光

  高级语言唯一的任务就是,提供一个唯一的,无歧义的,足够清晰的语意让编译器去理解,去使用汇编代码实现那个语意

  何谓 唯一的,无歧义的,足够清晰的语意?

  判断的标准,随着技术的进步而不同

在当前的技术条件下(耶稣历2010年,共和国历61年 )

"定义一个int类型的变量,并把它赋值为1"这是一个唯一,无歧义,足够清晰的语意

"给我编译一个论坛抢SF的机器人吧~"这不是一个唯一,无歧义,足够清晰的语意

不要被C的语意表述方法所局限 ,我曾有幸见识过一些cobol语言的代码,当时给我的感觉,就像是触电… …

同样在第三天发生的事情

  第三天,一切都变得前所未有的好起来,一切又都变得前所未有的糟糕起来

  编程的效率已经大大提高了,越来越多的大型项目却陷入了泥潭

  库,框架,等概念,开始萌芽.. ..

  程序员们,陷入了思考

第四天,程序员说,我们需要一个更聪明的编译器

  第三天,程序员说,我们需要一个更聪明的编译器,于是这个世界上,便有了能替我们做更多的编译器

  面对对象的思想开始出现,并迅速的成为潮流,一大推面对对象的编程语言开始出现

其实,这一切的一切,只不过是编译器的一个把戏,具体的实现,可以参看本人的另一篇博文

 http://blog.csdn.net/only_lonely/archive/2010/03/14/5378076.aspx

 有必要的提示:

很多时候,真像需要时间才能够被看清,当我们回顾历史的时候,经常一眼就看穿前人所犯下的错误,这并不是因为我们比那些先驱者更明智,而是因为我们经过了时间的积淀,一切浮华,虚假,谎言都是经不起时间的考验的

  同样的,生活在我们这个时代的人,也很容易被这个时代的一些东西所困惑

   面对对象只是开发软件的一个方法之一,尽管它是多么的优秀,多么的高效,但它不是神,只是可选的方案之一,任何多余的崇拜或鄙夷,都会使得你心生抵触,错过一个又一个看清真像的机会

 

第四天的成功者之一 C++

完全兼容C是C++的成功原因之一

不知是C++兼容C的原因,还是C++本身的原因

C++是一种给人无限可能的语言

同时,也是一门让人看清真像的语言

尽管,有时候``它的语法很让人纠结,但还是有必要去了解一下

第五天 不完美的补偿

还记得java那句激动人心的口号吗?

"一次编译,处处运行"

这个口号曾经令多少人兴奋到夜不能寐,即使所谓的"一次编译,处处运行"已经变成了现在的"一次编译,处处调试",但我想很多人,依然记得第一次接触java时的那种感叹,虽然我没有那个亲身的经历(我是一个C#er :-) ),但我能明白那种感觉

其实,这只是对当初犯错的一个补偿

据说Java的运行,就是在操作系统上加一层虚拟机,抽象掉操作系统的细节

我们犯了一个错,在操作系统兴起的时候,没有定义统一的,抽象的操作系统功能接口,如果当初那么做了,事情会简单许多许多!

如今不同操作系统之间的隔阂,已经成为割裂程序界的一道巨大伤疤

聪明的程序员,试图弥补这些,于是便出现了java,出现了虚拟机,并在这条路上,越走越远

不去谈论java与C#之间的优劣,是一个明智的选择

而且我完全不懂java,也没有那个资格去谈论

本博的主要目的,就是谈论.net在第四天所做的事情,于是就不在此多说

  唯一要说明的是 .net 不只是一个虚拟机~,它还有更多,更让人惊讶的特性

最后,程序员不是上帝

  若要崇拜,迷信某样东西,那它必须足够强大,足够神秘,完全超过人类的认知范围

  很显然,程序员不是上帝,他很普通,平凡,甚至许多时候很自负

  因此,我们并不需要去迷信,去崇拜程序员创造出的世界

  试图去了解它,不要心怀畏惧

一切都会呈现在你面前

only_lonely 原创 转载请注明出处

拍砖您随意~只要有理,我一会心怀感激的接受  :-)

posted @ 2010-03-16 19:59 only_lonely 阅读(224) 评论(1) 编辑
 

2010年3月15日

C#如何识别引用的真实类型(一)
摘要: 声明 : 本文的绝大多数灵感与资源均来自 <<.net 本质论>>,本人仅仅是在个人理解的基础上,加以翻译,节选.如果与原书有任何冲突,或者不明晰的地方,请阅读原文,并以原文为主知识储备,如果您已经十分熟习这些,可以跳过1 什么是引用?引用是一个数据结构,包含了一个计算机内存堆地址的值,就类似C++中的指针一样,本文中所有出现有关"引用"字句,读者都可以把它理解成C,C++...阅读全文
posted @ 2010-03-15 21:43 only_lonely 阅读(93) 评论(0) 编辑
 
容易被忽视,错用的构造函数 .cctor-- 静态构造函数
摘要: .ctor 是大家都知道的.cctor 却不被人所熟习,也很容易被误用所谓的的 .cctor 放在C#的语法中,就是静态的构造函数形如class A{ static A() // 这就是一个.cctor构造函数}.cctor 与 .ctor之间的异同 1,不能有访问权限标识符 public,private,等等,都不能使用,这与.ctor不同 2,不能有返回值,这与.ctor相同 3,不能有参数,...阅读全文
posted @ 2010-03-15 21:41 only_lonely 阅读(59) 评论(0) 编辑
 
仅列出标题