诗剑书生的专栏

我在灌江口上住,花开花落,不知流年度.雁过空遗秋色暮,抚琴细听梧桐雨. 轻舞残虹漫展书,云卷云舒,思愫万千缕.安得婵娟与共处,长作识字耕田夫.                   诗剑书生 于灌江口.听潮居

诗剑书生ID:axman
101562次访问,排名831好友1人,关注者6
一个男人. 一个写程序男人. 一个写程序并从程序中寻找快乐的男人. 一个写程序并从程序中寻找快乐又把快乐传递给大家的男人.
一个书生. 一个寂寞的书生. 一个寂寞的梅香竹影下敲声写韵的书生. 一个寂寞的梅香竹影下敲声写韵晨钟暮鼓中逸气扬剑的书生.
那个男人是位书生。没有人知道他的姓名,居无定所,行无定踪,亦耕亦读,或渔或樵。
axman的文章
原创 87 篇
翻译 0 篇
转载 0 篇
评论 157 篇
axman的公告
最近评论
guiji01:s+1中,+操作有两个操作数,JVM指令中+操作最小类型是int,byte,short,char都以iload,iadd来操作

老大你要注意标点符号。。。。,byte、short、char之间用顿号吧。不过我试了一下,顿号不好打出来,也怪我看的不认真,费了挺长时间。。。
guiji01:哈哈,大概半年前看java的一系列的基础概念时,百思不得其解时,看到了您的文章,确实写的很好,很好。

虽然现在有些地方仍然一知半解,最近找工作,这两天准备再次拜读。

ps:n久不来csdn了,专门登陆致谢!真的很希望能认识您。dodoryan#gmail.com
axman:GPRS模块拨号上去以后可以浏览网页,说明你用cmnet拔上去的,而MMS应该用cmwap拔号.
weiquanqiang:请问楼主我用GPRS模块拨号上去以后可以浏览网页,但我在用程序发送彩信时候总是提示“无法连接到到远程服务器”,这是什么原因呀????
chinagavin:你为什么不写书呢??
写什么书我都支持,一定买。
文章分类
收藏
    相册
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 C#与.NET 3.0高级程序设计(特别版)问题与错误列表收藏

    新一篇: 在C#中完成海量数据的批量插入和更新 | 旧一篇: 从OLE到SOA,SOA其实很简单!

    这是一本称为“圣经”的书,入手初看了一下,称“圣经”确实勉强了。其中一些深入的问题作者根本没有理解。

    当然首先肯定书不失为一本好书,但问题还是不少,现择录于此。希望再版时能有所修正。

    我边读边往这里加。

    -------------------------------------------------

    如何看"圣经"?

    人类历史上那些曾经在某一时期辉煌的经典如璀璨的明星指引着历史中的人们不断前进.但是任何经典都是历史的

    产物,也归终于历史........

    象thinking in java,或者如同本书,在新技术发展的最初阶段,大多数学习者没有渠道系统全面地了解某一知识体系

    的时候,这样的书籍无疑是学习的圣经.就如78年左右"中国的改革开放政策",还被红色的余辉照耀下的人们,对于这

    种能给他们的生活,他们的思想带来翻天覆地的变化的伟大思想,除了"圣经"这样的词不足以形容其伟大.但是放眼

    今天,学过历史的初中生都已经非常深入地理解和明白"改革开放"的思想内涵和历史背景.在他们眼中,这个政策是

    "本应如此"的,何以见其伟大?

    反过来说,对于java技术在中国已经有十多年的深入推广,.NET技术在中国已经有五年以上成熟的应用.这些当初的

    经典在现在已经显现不出其高深和神圣.说实话我当初对TKJ的崇拜并不比别人低,但现在回过头来看看不过如此.这

    本书谈不上思想,最多可以说是比较全面的比较深入地JAVA技术大全.这是任何一个水平在不断发展的技术人员对待

    一部经典的正常心理,我们不能否认它们在当初的神圣和辉煌以及它给我们的能力提高所起的巨大指导作用.但我们

    也坚决不能把它奉为永恒的经典!回过头来批判地看待正是对它的尊重与怀念.

    本着同样的心情,本书出致3.0版,已经称不上圣经.非常简单的一个道理,因为一本书的升级永远不会比你的技术水平

    的提高快.就我下面的这些问题,如果在此书第一版面市的时候我就能认识这些问题,那我可能就是全球顶级大牛了.

    但我不是,我连普通高手都不是,只是我的水平这本书本身提高得快而已.

    -------------------------------------------------

    第63页下面那个图说明
    public const string BestNbaTeam = "timberwolves";是常量的例子的图中编译后成.field public static literal string BestNbaTeam = "timberwolves"根本说明不了它是常量,应该加上一句调用:
    Console.WriteLine(BestNbaTeam);编译后是 ldstr "timberwolves"而不是ldsfld string className::BestNbaTeam这才能说明问题.

    -------------------------------------------------

    64/65页对readonly的描述不准确确,不是不能改变而是一经赋值就不能重新赋值,简单说变量只能永远指向

    最初的那个对象.不能重新赋值,但对象本身可以改变.

    static readonly StringBuilder sb = new StringBuilder("axman");
    static void Main(string[] args)
    {
    Console.WriteLine(sb.ToString());
    sb.Append(' is a great person!');
    Console.WriteLine(sb.ToString());
    Console.ReadLine();
    }
    你完全可以改变sb指向的对象的内容.但你不能再把它指向另一个对象.

    static void Main(string[] args)
    {
    sb = new new StringBuilder("axman1");

    Console.ReadLine();
    }

    其实这和java中final变量的意思是一样的. 

    -------------------------------------------------

    92页的Equals实现还是存在重大设计性错误。作者对陷井并不了解。
    按作者的想法实现下面的类,看看是什么结果?
    a==b,但b!=a


    class Person {
    public string name;
    public int age;
    public Person(string name,int age) {
    this.name = name;
    this.age = age;
    }


    public override bool Equals(object obj)
    {
    if (obj != null && obj is Person) {
    Person temp 
    = (Person)obj;
    if (temp.name == this.name && temp.age == this.age) return true;
    }

    return false;
    }

    public override int GetHashCode()
    {
    return base.GetHashCode();
    }

    }


    class ChinaPerson : Person 
    public string city;
    public ChinaPerson(string name, int age,string city) : base(name,age)
    {
    this.city = city;
    }

    public override bool Equals(object obj)
    {
    if (obj != null && obj is ChinaPerson)
    {
    ChinaPerson temp 
    = (ChinaPerson)obj;
    if (temp.name == this.name && temp.age == this.age && temp.city == this.city) return true;
    }

    return false;

    }

    public override int GetHashCode()
    {
    return base.GetHashCode();
    }

    }

    static class Program
    {
    static void Main(string[] args)
    {
    ChinaPerson cp 
    = new ChinaPerson('axman'100'bj');
    Person p 
    = new Person('axman',100);
    Console.WriteLine(p.Equals(cp));
    Console.WriteLine(cp.Equals(p));
    Console.ReadLine();
    }

    }

     

    -------------------------------------------------

    142页对于引用类型转换,仍然采用了笨拙的方法,浪费性能。

    if(e is Manager){

    ((Manager)e).XXX;

    }

    这样的调用首先e is Manager要做isinst操作来测试类型,然后再调用castclass来强行转换。

    而Manager m = e as Manager只需做isinst,如果返回真就直接用stloc.x操作将e的地址赋给了m.

    后面我们只需判断if(m == null)或m!=null来操作m就行了。稍有水平的 .NET程序员应该坚决避免先isinst再

    cstaclass这种耗时的操作。

    有人说"这里"只是为了说明问题举的简单的例子,没有必要"刻意"表现性能,那么看223页,作者在"刻意"下仍然不

    知道直接用as 来简化操作.

    -------------------------------------------------

    第197/199的clone实现实在是搞笑/愚蠢/无效

    首先,197中.

    public object Clone(){return new Point(this.x,this.y);}

    这种行为本身就是一种非常搞笑的,别说实现得好不好,有这种思维就是一个愚蠢的行为.

    clone的目的是什么?就是要通过"复制"而不是new 的方式来生成一个和已有对象状态一致的对象.如果用new 来

    实现clone,那么调用者自己不会new ?你new的动作比调用者萧洒?由你new出来的对象比调用者自己new出来的

    对象更好控制?既然是new出来的那为什么没事找事加上一个clone?所以这种实现本身就违反clone的意义.且不说

    实现得好不好了.

    我们再看199页所谓的深复制,Point的成员变量PointDescription有一个成员变量petName,所以作者new 了一个

    PointDescription又复制了petName.如果PointDescription的成员变量又包含成成员变量,这样多级的引用呢?按

    作者实现思路如何递归并反射进行赋值?如果是私有成员变量你还能给它赋值?这样的代码能实现真正的深复制?

    我就想不通一般普通程序员都知道的用序列化实现对象的深复制,到了大师手里就这么难呢?

            public object Clone() {
                BinaryFormatter bf = new BinaryFormatter();
                MemoryStream ms = new MemoryStream();
                bf.Serialize(ms, this);
                ms = new MemoryStream(ms.ToArray());
                return bf.Deserialize(ms);
            }

    这样一段对所有要实现深复制的对象都适用的代码难道不比那种要手工不断递归赋值也不能完全深复制的代码强?

    我们要做的仅仅是在类前面加一段    [Serializable]而已.(不要钻牛角尖说有些字段不可序列化,那样的情况先反序列化得到一个新对象后再手工生成不可序列化字段也比递归反射再一个一个赋值要高明且完全得多)

    -------------------------------------------------

    第213页最下面"奇怪的是,同步Invoke()不能直接在C#中调用",我奇怪的是我为什么有直接调用?RP问题?

        delegate void Test();

        class Program
        {
            static void t() {
                Console.WriteLine("Axman!");
            }
            static void Main(string[] args)
            {
                Test t1 = new Test(t);
                t1.Invoke();
                Console.ReadLine();
             }
        }

     

    -------------------------------------------------

    第267页 使用泛型后加入值类型后,作者说从编译后的IL看到没有Boxing和Unboxing操作,虽然结果巧合是正确的,

    但这个说明是完全错误的,假如泛型也是完全基于堆来实现,List<int>对象的Add方法完全可以接收一个值类型后

    在方法类Boxing,获取方法完全可以在方法内UnBoxing后再返回值类型.仅从编译后那几行IL不可能说明泛型没有

    执行Boxing和Unboing操作.真正说明问题的是显示List<int>对象的_items成员,这个成员是根据传入的类型生成

    的该类型数组,List<int> 时就是int[ ] 数组来存放Add加入的数据,这才可以说明没有发生Boxing和Unboing.

    -------------------------------------------------

    第161页 对表示状态的关键全局变量的改变竟然没有同步,disposed = true;完全是一个初级程序员的思维,任何

    两个线程同时运行都有可能使这个"正式的可处置模式"失败.

     

    发表于 @ 2008年03月05日 12:01:00|评论(loading...)|编辑

    新一篇: 在C#中完成海量数据的批量插入和更新 | 旧一篇: 从OLE到SOA,SOA其实很简单!

    评论

    #turingbook 发表于2008-03-06 13:19:52  IP: 221.223.20.*
    对这种深入的批评致以最高敬意。

    可以写封邮件和原作者讨论一下,有可能使全球无数人受惠。
    #YuLimin 发表于2008-03-15 12:01:08  IP: 210.21.68.*
    哎,老大,我不明白你为何拒绝写书?
    #axman 发表于2008-03-15 18:06:21  IP: 123.115.5.*
    当年我敲声写韵,为一字之合仄切律而苦吟久咏,成诗之难不可道与边人说.但是有人把一行白话断成多行就叫诗.所以我从此就不发表诗了.
    看看市场上那些技术书,如果我的书也和那些书并列摆在一起,对我而言不是成就感,而是辱没感.
    我不写书不是因为我谦虚,反而是因为我自视甚高,说句难听的就是自大狂妄吧.
    #oneyear2008 发表于2008-03-17 20:27:48  IP: 222.247.57.*
    司令:确实去写书,那更好。。。。。。。。


    谢谢!!!!
    #chinagavin 发表于2008-03-24 02:26:19  IP: 123.116.96.*
    axman
    说实在的,你确实是我看到的少有的技术牛人。
    比很多论坛、网站上所谓的高手要强的多的多,
    如果你写书,我必买。
    记得通知最好了。不然不知道啥时候呢。
    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © axman