《你必须知道的.NET》,勘误支持

勘误支持
http://www.anytao.com/
anytao@live.com
返回主页

虽然作者、审稿和编辑花费了大量的时间对书稿进行了反复的修改和推敲,但是限于时间和水平,仍难避免失误或错误。为了使本书能更好地服务于读者,请您将关于本书的任何错误信息发至以下任何链接:

  • 作者个人邮箱:anytao@live.com
  • 本书支持网站:http://book.anytao.com/
  • 博文视点网络:http://www.broadview.com.cn/

     

    勘误列表

    按照页码,错误内容,致谢人的顺序排列

    [P3、P4、P8],印刷错误,删除书中无故出现的[0]符号,致谢:lr

    [P5],书写错误,表1-1第2行,将“pubic”改为“public”,致谢:韩现龙

    [14],书写错误,第11行,将“所有方法复制一份”改为“所有虚方法复制一份”

    [P17],图例错误,图1-6中,将第二个“Class1”改为“Class2",致谢:彭渊

    [P18],书写错误,倒数第10行,将”通常情况下在改变原有体系的条件下“改为”通常情况下在不改变原有体系的条件下“,致谢:孟维然

    [43],书写错误,第4行,将“2.2节”改为“1.2节”,致谢:AGPSky

    [P53],重复论述,删除第一行“接口可以作用于值类型和引用类型,并且支持多继承。”

    [P81、P163、P155、P190、P191],书写错误,将“显示”改为“显式”

    [P98],书写错误,表3-1第8行第2列,将“System.64”改为“System.Int64”,致谢:韩现龙

    [P166],书写错误,第7行,将“Icomparable”改为“IComparable”,将“Iconvertible”改为“IConvertible”

    [P176],图例错误,图5-1、图5-2、图5-3中,"c='A', x = 100,返回地址"的上下顺序颠倒了,应该从上到下是“返回地址”-->“x = 100”--> "c = 'A'",致谢:彭渊

    [P190],书写错误,倒数第2行,将“实现虚构函数”改为“实现析构函数”

    [P222],代码错误,第3行,删除“执行Audio.Audio(string name, int speed)。”,致谢:qlwy

    [P227],书写错误,倒数第2行,将“IDispose”改为“IDisposable”

    [P357],表述错误,将“JIT根据“abcdef”在哈希表中逐个查找”改为“JIT根据“abcdef”的Hash Code在哈希表中进行查找”,致谢:abatei

    [P277],代码错误,在第一行代码段开始加入“[Flags]”特性声明

    [P353],书写错误,最后一行,将“类似与”改为“类似于”

    [P362],书写错误,倒数第5行,将“指向Char数值”改为“指向Char数组”

    [P408],书写错误,表9-1第7行第2列,将“Sytem.Web”改为“System.Web”,致谢:韩现龙

    勘误表下载

  • posted @ 2008-04-30 00:58 Anytao 阅读(1030) 评论(62)  编辑 收藏 所属分类: A DotNetQ Anytao.Book.InsideDotnet

      回复  引用    
    #1楼 2008-05-02 02:24 | CppGohan [未注册用户]
    你好,我也有疑问,就是177页那个栈是先进先出错了应该是先进后出,还有那几张栈上内存分配的图是不是也有点问题。您的书让我学到不少,以后会继续关注您的博客。
      回复  引用  查看    
    #2楼 [楼主]2008-05-02 22:36 | Anytao      
    @CppGohan

    谢谢您的提醒,已经在勘误表中列出:
    [P176],图例错误,图5-1、图5-2、图5-3中,"c='A', x = 100,返回地址"的上下顺序颠倒了,应该从上到下是“返回地址”-->“x = 100”--> "c = 'A'",致谢:彭渊

    也同时谢谢CppGohan:-)也包括图5-4
      回复  引用  查看    
    #3楼 2008-05-09 21:17 | designbook      
    脸红了,这么多错啊?!
      回复  引用  查看    
    #4楼 [楼主]2008-05-10 10:24 | Anytao      
    @designbook
    我也是,继续努力,打造更好。
      回复  引用  查看    
    #5楼 2008-05-12 14:22 | Edwin dong      
    怎么这么多错误啊,我刚来了这本书,才看了几张,看来以后要多来这里看看,免得自己理解错了都还不知道啊。
      回复  引用    
    #6楼 2008-05-12 16:26 | 读者 [未注册用户]
    P80中的[在父类和子类的具体实现中,必须严格把握继承层次中的关系和特征,将基类替换为子类,程序的行为不会发生任何变化。同时,这一约束反过来则是不成立的,子类可以替换基类,但是基类不一定能替换子类。]将基类替换为子类是不是应该改为将子类替换为基类?
      回复  引用  查看    
    #7楼 [楼主]2008-05-12 22:29 | Anytao      
    @Edwin dong
    给你的阅读带来困难,很抱歉前期的失误和大意,勘误信息将会第一时间发在这里,同时一定在二版中解决这些问题,谢谢您的关注,更多思考可以邮件联系:-)
      回复  引用  查看    
    #8楼 [楼主]2008-05-12 22:42 | Anytao      
    @读者
    这是Liskov原则的详细表达,还是以一个简单的实例来看这个问题,例如:

    public class Father
    {
    public virtual void M()
    {
    Console.WriteLine("Do something by Father");
    }
    }

    public class Son : Father
    {
    public override void M()
    {
    Console.WriteLine("Do something derived by Son.");
    }

    public void N()
    {
    Console.WriteLine("Do something by Son");
    }
    }

    public class ActionEx
    {
    public void FatherSay(Father father)
    {
    father.M();
    }

    public void SonSay(Son son)
    {
    son.N();
    }

    public static void Main()
    {
    ActionEx action = new ActionEx();

    //基类可以替换为子类
    action.FatherSay(new Son());

    //子类不能替换为基类
    //action.SonSay(new Father());
    }
    }
      回复  引用    
    #9楼 2008-05-13 12:02 | 读者 [未注册用户]
    谢谢楼主!是我对[基类可以替换为子类]这句话理解有问题,现在搞清楚了。
      回复  引用  查看    
    #10楼 [楼主]2008-05-13 22:54 | Anytao      
    @读者
    呵呵,可能我表达的也不够清晰吧:-),谢谢你的讨论
      回复  引用    
    #11楼 2008-05-14 13:26 | thinksand [未注册用户]
    国内很少有这样用心做书的,希望楼主以后每一本都能保持这样的热忱
      回复  引用  查看    
    #12楼 [楼主]2008-05-15 00:02 | Anytao      
    @thinksand
    :-)
    谢谢你的夸奖,说实话有很多工作不到位,写书并非我的专职,但是确实兴趣之一。希望自己的努力能有更多的收获,打造一本精品还是很不容易,受益于更多的人。
      回复  引用  查看    
    #13楼 2008-05-17 15:49 | A.feng..      
    王涛大哥,我又来了:-) 书上98页第4行,"int指令表示.."这里应该是init指令吧,书写错误了~
      回复  引用  查看    
    #14楼 [楼主]2008-05-23 22:32 | Anytao      
    @A.feng..
    :-),不好意思,又一个书写错误
      回复  引用    
    #15楼 2008-05-26 18:18 | Davis_Xu [未注册用户]
    请楼主看282页面,“CLR允许接口可以包含事件、属性、索引器、静态方法、静态字段、静态构造函数以及常数。但是注意:C#中不能包含任何静态成员。”

    请问这两句怎么理解?是否印刷有误?谢谢!
      回复  引用  查看    
    #16楼 [楼主]2008-05-27 11:17 | Anytao      
    @Davis_Xu
    并无笔误,并不矛盾,一个是CLR的规则,一个是c#规则:-)
      回复  引用    
    #17楼 2008-05-29 11:57 | Davis_Xu [未注册用户]
    @Anytao
    请问楼主,以上两句是否可以如此理解:C#接口不能包含任何静态成员,并且,其可包含的成员,只能是CLR允许接口包含成员列表的一个子集?多谢指点!
      回复  引用  查看    
    #18楼 [楼主]2008-06-01 22:34 | Anytao      
    @Davis_Xu
    我理解是这样的。
    CLR层是允许定义静态成员的,但是CLS兼容的接口类型则是不允许的。在我看来c#中不能包括静态成员的规则是合理的,无静态类型的接口更能体现接口存在的意义。
      回复  引用  查看    
    #19楼 2008-06-23 20:00 | RainSky      
    P21 倒数第五行 面向对象原则:多组合,少继承 应该是 多聚合 吧?前面讲的是多聚合
      回复  引用  查看    
    #20楼 [楼主]2008-06-23 23:49 | Anytao      
    @RainSky

    您好。谢谢你的提醒。
    关于组合与聚合的说法,其实都是正确的,对继承而言,组合与聚合都代表了一种区别与继承的关联关系,所以都可以认为是正确的。
    如何有兴趣可以参考书中P17页关于聚合的论述。

    再次感谢您的讨论。

      回复  引用    
    #21楼 2008-07-03 14:16 | finer [未注册用户]
    因为有这么多勘误,所以想在第二版时再买,什么时候出第二版呢?
      回复  引用  查看    
    #22楼 2008-07-04 15:14 | AGPSky      
    P43页 上数第4行 “参阅本章2.2节” 是不是应该为1.2节。
    另外 在什么是继承 那里没看到明确的通过什么方式实现虚拟函数的动态绑定方式。
    指导。
      回复  引用  查看    
    #23楼 2008-07-04 15:22 | AGPSky      
    再请教一个问题,请AnyTao老师回答一下。谢谢
    P44页上面关于调用方法的时候,直到找到第一个覆写方法调用才结束。能不能出现没有覆写的方法,只有基类方法。如果这样了,怎么结束,是直接调用基类方法吗?
      回复  引用  查看    
    #24楼 2008-07-08 15:21 | AGPSky      
    P100 Il装载指令 ldc 行 ldc.i4 5 是不是应该 ldc.i4.5 呢。上面的代码有类似的。
      回复  引用  查看    
    #25楼 [楼主]2008-07-09 01:28 | Anytao      
    @finer
    第二版还未在日程之内,可能还得一段时间,很抱歉一版的失误。
      回复  引用  查看    
    #26楼 [楼主]2008-07-09 01:31 | Anytao      
    @AGPSky
    谢谢你的勘误。

    关于虚方法的动态绑定,“什么是继承”中从方法表的产生过程分析了对象创建的内存情况,对于虚方法的动态绑定问题,这是一个从基本面的分析,可能未能完全阐述关于动态绑定的所有概念。

    这个问题,可以考虑以专门的篇章来补充,希望二版有所更新:-)
      回复  引用  查看    
    #27楼 [楼主]2008-07-09 01:35 | Anytao      
    @AGPSky

    如果没有覆写任何虚方法,则将执行相应的基类方法,这样实现在语法上是可行的。但是将失去多态特性的面向抽象的设计思路,整个实现步入僵化的泥潭。
      回复  引用  查看    
    #28楼 2008-07-09 10:43 | AGPSky      
    P212页,上数第五行 另外开始到例如:
    上面提到说访问基类成员可以通过base修饰符完成,然后说例如,那么这个例子里面是不是应该有base嘛,不知道是我理解的有问题还是疏忽了。
      回复  引用  查看    
    #29楼 [楼主]2008-07-12 01:20 | Anytao      
    @AGPSky
    示例主要阐述的是“new作为修饰符,用于向基类成员隐藏继承成员。”这一主题,没有特别说明base方法基类成员,对base的介绍放在了6.2节中,感谢你的细致,这个“例如”放得不是位置:-)
      回复  引用  查看    
    #30楼 [楼主]2008-07-15 00:35 | Anytao      
    @AGPSky
    ldc.i4 5也是正确的表达方式:-)
      回复  引用  查看    
    #31楼 2008-07-15 19:39 | 金色海洋(jyk)      
    [0]我还以为这个有什么含义呢,也需要加个注释,原来是印刷错误呀。

    我也发现了一个

    P5 表1-1 “访问修改符”,下面的表里面是 “访问修饰符”。
      回复  引用  查看    
    #32楼 [楼主]2008-07-15 23:47 | Anytao      
    @金色海洋(jyk)
    谢谢老金的提醒,我脸红的不行了
      回复  引用  查看    
    #33楼 2008-07-16 21:43 | 金色海洋(jyk)      
    p30 中间:

    “提供稳定的对外接口。因此,系统中相对稳定部分常被抽象成接口。”

    按照我的理解,应该是把变化的部分抽象成接口呀,就像《深入浅出设计模式》里面的策略模式里的,鸭子的叫和飞,都从鸭子基类里分离出去了,变成了一个接口。

    不知道我的理解对不对?

    或者说,内部可以随意变,但是对外的函数(名称和参数,包括接口)不能变化。
      回复  引用  查看    
    #34楼 2008-07-16 21:44 | 金色海洋(jyk)      
    打字打错了,很常见,我用拼音,也总是弄错了,写的字数少还能看一遍,多了就不爱看了。呵呵。
      回复  引用  查看    
    #35楼 [楼主]2008-07-16 22:42 | Anytao      
    @金色海洋(jyk)
    我的理解是,封装的是变化,但抽象的是稳定,所以是基于这个点儿写的。

    --引用--------------------------------------------------
    金色海洋(jyk): 打字打错了,很常见,我用拼音,也总是弄错了,写的字数少还能看一遍,多了就不爱看了。呵呵。
    --------------------------------------------------------

    太多的错误是这样造成的
      回复  引用  查看    
    #36楼 2008-07-17 12:52 | 金色海洋(jyk)      
    >>我的理解是,封装的是变化,但抽象的是稳定,所以是基于这个点儿写的。

    这么说倒是可以,但是书上的说法容易产生误解呀。如果我没有看到鸭子的策略模式的话,一定会以为把固定不变的做成接口呢。
      回复  引用  查看    
    #37楼 [楼主]2008-07-17 19:53 | Anytao      
    @金色海洋(jyk)
    呵呵,我考虑考虑这个说法,其实关于封装变化在第一章中有很多地方有所论述,基本的思想是一致的:-)
      回复  引用  查看    
    #38楼 2008-07-23 15:52 | AGPSky      
    P119 上数第三行 而基于安全机制的考虑,则在引用类型中以call(这里是不是应该是callvirt)指令来调用非虚方法会更安全。

      回复  引用  查看    
    #39楼 2008-07-25 11:02 | AGPSky      
    P148 下面代码和p149页上部代码中 ,是不是应该有个对形参的注释呢。
    实参注释了,形参应该也有一个哦。

      回复  引用  查看    
    #40楼 2008-07-25 15:25 | AGPSky      
    P177
    下数第五行,FILO应该是先进后出吧。书上写先进先出了。

      回复  引用  查看    
    #41楼 [楼主]2008-07-25 21:24 | Anytao      
    @AGPSky
    呵呵,当时觉得书中已经解释清楚了,就没有特别注释形参。
      回复  引用  查看    
    #42楼 [楼主]2008-07-25 21:30 | Anytao      
    @AGPSky
    谢谢你的勘误:-)
      回复  引用  查看    
    #43楼 2008-07-31 14:38 | AGPSky      
    我又来了
    P312
    在静态类与非静态类的总结的第三点
    相对与非静态类来说 这里的“相对与”应该是:“相对于”吧。
      回复  引用  查看    
    #44楼 2008-08-01 13:30 | AGPSky      
    不好意思又来一次
    p340
    倒数第一行文字“从可以提供”
    这里读起来不通顺呢。少字了吗?
      回复  引用  查看    
    #45楼 2008-08-05 16:00 | 阿豹      
    p94 倒数第二行 “打开.NET Framework SKD命令提示行”里的“SKD”应改为“SDK”;
    P96 正数第二行“简单的ILadsm.exe”应该是“ILdasm.exe”;
      回复  引用  查看    
    #46楼 2008-08-05 16:07 | 阿豹      
    p138 使用explicit或者implicit进行用户自定义类型转换一个代码事例书中印刷为:

    //强制custom类型转换为VipCustom类型
    public static explicit operator VipCustom(Custom user)
    {

    }

    应该是:
    static public explicit operator VipCustom(Custom user)
    {

    }

    因为自定义类型转换的格式是:
    static 访问修饰操作符 转换修饰操作符 operator 类型(参数列表)


      回复  引用  查看    
    #47楼 2008-08-06 18:00 | Astar      
    P112页的:(对应的IL代码为:)第九行"Static Mehtod()"应为"StaticMehtod()"吧.
      回复  引用  查看    
    #48楼 2008-08-09 18:22 | gecko      
    您好,王涛老师。

    至上次您介绍我看您的书之后,我十分投入的学习。

    在看您的《你必须知道的.NET》一书时,在109页遇到一非常费解的话,如下:
    "ldc.i4.5",将5个4字节长度整数压入栈顶,对应于arrChars=new char[5]."

    抱着不解与质疑,我上网找了一下,有另外一个对ldc.i4.5的说法。如下:
    "ldc.i4.2 //i4 代表這是一個4byte 的整數(integer),而最後的2 則是它的值。也就是說,這行指令會將一個內容為2 的4byte 整數放入堆疊之中。"
    出处:http://sun.cis.scu.edu.tw/~nms9115/articles/dotnet/msil/MSIL.pdf

    不知道这两个说法,哪个更确切呢?还等您的回答。
    十分期待您能回我电子邮件95316851@qq.com。

      回复  引用  查看    
    #49楼 2008-08-09 19:14 | gecko      
    老师,我自己试着写一个程序验证了一下。
    原cs文件如下:
    using System;

    class SetValue
    {
    public static void Main()
    {
    int i;
    i=5;
    }
    }


    编译后,反编译的IL对应如下:
    .method public hidebysig static void Main() cil managed
    {
    .entrypoint
    // 代码大小 4 (0x4)
    .maxstack 1
    .locals init (int32 V_0)
    IL_0000: nop
    IL_0001: ldc.i4.5
    IL_0002: stloc.0
    IL_0003: ret
    } // end of method SetValue::Main


    我觉得更符合上面的第二个说法:
    "ldc.i4.2 //i4 代表這是一個4byte 的整數(integer),而最後的2 則是它的值。也就是說,這行指令會將一個內容為2 的4byte 整數放入堆疊之中。"

    还请您指点一二。

      回复  引用  查看    
    #50楼 2008-08-10 08:18 | Astar      
    又来了----
    这个不知道是我理解错了,还是Anytao本来就是这样写的:
    P160:4.4.3 “原理分拆” 还是 “原理分析”
      回复  引用  查看    
    #51楼 2008-08-11 16:09 | gecko      
    老师您什么时候上线回答啊...
    要看下去,又得等你的回复..
    实在是按捺不住啊.......
      回复  引用  查看    
    #52楼 [楼主]2008-08-11 22:43 | Anytao      
    @gecko
    很抱歉,这几天看疯看奥运,一直没有上线。

    "ldc.i4.5",将5个4字节长度整数压入栈顶,其中少了一个“这”字,正确的表述是“将5这个4字节长度整数压入栈顶”,我已经不清楚出版哪个环节出了差错,引起如此大的理解误差实在抱歉:-)

    在书中P100页表3-2中对ldc.i4 5进行过描述,你可以参考一下。

    非常感谢你的指正。
      回复  引用  查看    
    #53楼 [楼主]2008-08-11 22:59 | Anytao      
    @AGPSky

    P312中,好像“相对于”更好;

    p340中,应该是“从而可以提供”。

    谢谢:-)
      回复  引用  查看    
    #54楼 [楼主]2008-08-11 23:11 | Anytao      
    @阿豹

    --引用--------------------------------------------------
    阿豹: p94 倒数第二行 “打开.NET Framework SKD命令提示行”里的“SKD”应改为“SDK”;
    P96 正数第二行“简单的ILadsm.exe”应该是“ILdasm.exe”;
    --------------------------------------------------------

    拼写错误,谢谢你的仔细:-)
      回复  引用  查看    
    #55楼 [楼主]2008-08-11 23:14 | Anytao      
    @阿豹

    static public explicit operator VipCustom(Custom user)
    {

    }

    static 和 public的顺序并没有严格的规定,所以上述两种表达方式都是相同的:-)
      回复  引用  查看    
    #56楼 [楼主]2008-08-11 23:37 | Anytao      
    @Astar

    应该为StaticMehtod,从ildasm拷贝过来,不知怎么回事儿:-)

    P160:4.4.3 “原理分拆” 还是 “原理分析”
    为“原理分拆”通过对装箱、拆箱两个过程进行分拆描述,就是这个意思:-)
      回复  引用  查看    
    #57楼 2008-08-29 10:12 | Justin      
    [41],书写错误,第3行,“对原系统进行修改的继承上”,应该是“对原系统进行修改的基础上”。
      回复  引用  查看    
    #58楼 2008-08-29 11:51 | Justin      
    [96],书写错误,第2行,应该是ILdasm.exe。
    [98],书写错误,第1行,“int指令表示”,应该是“init指令表示”。
    [99],书写错误,倒数第3行,“而add.vof.un表示将两个无符...”,应该是“而add.ovf.un表示将两个无符...”。
      回复  引用  查看    
    #59楼 2008-08-29 14:08 | Justin      
    hi,P116,倒数第2行:“由于new关键字的阻断作用,隐藏了基类虚方法的实现”,这里有点疑问,你的意思是不是说阻断了子类虚方法的实现呀?

    对比son.DoVirtualWork()和aGrandSon.DoVirtualAll()
    son是Father类型时,虽然从IL看,都是在调用Father::XXX,但是因为前者是new方式,所以实际运行时走不到Son类里的方法,而后者因为是override方式,所以运行时可以走到Grandson类的对应方法里。

    这块我一直也有点模糊,你看看是不是这个意思?
      回复  引用    
    #60楼 2008-08-30 09:53 | AstarNoLogin [未注册用户]
    P389,下面的代码块中
    int a=1;
    int b=b;//??b=0??
    GetResultToText(a,0);???(a,b)?
      回复  引用  查看    
    #61楼 2008-08-30 14:07 | Justin      
    [123],书写错误,第3行,CRL应该是CLR。
    [124],书写错误,第8行,CRL应该是CLR。
    [133],书写错误,第6行,CRL应该是CLR。
    [133],书写错误,小标题:“1.通用有规则”应该是“1.通用规则”。
    [155],书写错误,第8行,CRL应该是CLR。
    [156],书写错误,第4、5行,CRL应该是CLR。
    [181],书写错误,倒数第1行,2.2应该是1.2。

      回复  引用  查看    
    #62楼 [楼主]2008-09-01 23:16 | Anytao      
    @Justin

    谢谢王兄的仔细勘误,我会及时更新勘误信息:-)

    关于P116的分析,我的理解是:

    关于new关键字,有一个误区就是new不光是阻断虚方法,其实核心的点我倒认为不必强调“阻断”,而应该着眼“隐藏”,用于向基类成员隐藏基础成员。虚方法是,非虚方法也是。

    基于这点,对于son.DoVirtualWork() 而言,由于new的存在DoVirtualWork没有覆写父类方法,而成为子类的“新”方法,所以调用DoVirtualWork实际执行的是Father的对应方法,注意调用是仅仅执行Father.DoVirtualWork,而不存在“走到”son.DoVirtualWorK一说。对于aGrandSon.DoVirtualAll()而言,由于没有new的隐藏,所以父类Grandson中的DoVirtualAll方法已经由子类覆写,执行aGrandSon.DoVirtualAll 实际执行的是子类的DoVitualAll方法,也没有走到Grandson类一说,因为直接调用的就是Grandson类相应方法。


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


    相关链接: