RSS 2.0 Feed
2005-01 Entries
摘要:Apple最近推出了Mac Mini,一个小盒子般大小的Mac计算机。其长度几乎就是我们电视遥控器的长度。很难想象这个小东西包含了一台计算机所需要的全部内容——Power G3处理器,DDR333内存,Ati Radeon 9200显示芯片,网卡,吸盘式光驱,齐全的接口……这些全集成在一个不到外置DVD光驱大小的盒子里。而且这个东西相对iMac,Power Mac来说很便宜,性能基本上能赶上iBook。苹果迷当然不会错过它: 在赞叹苹果出色的设计时,我无意中发现了这个:一种和Mac mini集成度媲美的PC mini!他比目前市面上的准系统更紧凑,更完善,买回来插上显示器就能用了,简直就是家电。嗯,这种东西要是不配Windows XP Media Center Edition就可惜了。 ...[阅读全文]

posted @ | Feedback (15) | Filed Under [ 闲话集锦 ]

摘要:Finalize,即.NET类型的非确定性析构器,将在对象被GC检查回收前调用。现在我关心一个问题,值类型,一般是自定义struct的析构器会不会被调用呢?一般值类型是在栈上分配,因此就不在托管堆上,不存在被GC回收的情况。但是我们要是将值类型装箱以后放在托管堆里了呢?他的析构器会不会被调用呢?由于C#和C++对析构器语法特别对待,我们不能在struct里面直接重写Finalize方法,因此这个实验只能用VB来做: Public Structure A    Public i As Integer    Protected Overrides Sub Finalize()        MsgBox("Hi, finalized")    End SubEnd Structure 在这个类里面,我们名目张胆地重写了Finalize,并且没有调用基类的Finalize,幸好VB对这种行为视而不见。首先我们检查是不是真的成功重写了基类的方法,用以下代码测试一下: Dim x As Object = New AGetType(Object).GetMethod("Finalize", BindingFlags.NonPublic Or _    BindingFlags.Instance _    ).Invoke(x, New Object() {}) 结果顺利显示了结果。接下来就进入主题,将该装箱后的对象抛弃在托管堆中,然后调用GC.Collect回收,看看是否能启动Finalize: Dim x As Object = New Ax = NothingGC.Collect() 结果……没有运行!?难道是这段代码无法达成调用Finalize的条件?我将Structure换成Class试试看,结果马上显示Finalize被调用了。这说明Finalize对值类型确实不管用。那么是不是因为CLR内部在某处对值类型自动调用GC.SuppressFinalize之类的方法注销了Finalize呢?那好,我们就多给他注册几个试试: Dim x As Object = New AGC.ReRegisterForFinalize(x)GC.ReRegisterForFinalize(x)......x = NothingGC.Collect() 结果,不管写了几次GC.ReRegisterForFinalize,在GC回收x的时候仍然没有Finalize运行的踪迹。看来,在CLR内部,值类型的Finalize是有特定规则的,不按照一般类的方式运行。我也没研究CLR的机制,没法再深究这个过程原理,以后有机会要好好看看……...[阅读全文]

posted @ | Feedback (10) | Filed Under [ 技术随笔 ]

摘要:前一段时间我介绍了泛型,其中有个很重要的特性叫“约束”。使用约束,可以减小泛型类型参数的取值范围,同时能够允许在泛型类型上应用所约束类型的功能。许多人为了在泛型类型上进行所需的操作,约束大量的类型。事实上,我觉得没有特别要求,泛型的类型参数应该尽量不约束任何类型,因为它会严重缩小你的泛型类的使用范围。而在类型参数上进行操作着一需求,并不是只能通过约束来达成。 规则:当你希望对类型参数实施的操作只用于你的泛型类一部分功能时,用辅助对象代替约束。 比如你希望编写一个容器类,它有很多功能,其中一个是排序。排序需要对象之间进行比较。如果容器类的其他功能并不依赖于排序,那么对整个类的类型参数使用约束就不合适。因为我们有可能根本不用排序,为什么还要有此约束呢。比如你将类写成: Public Class MyContainer(Of T As IComparable(Of T))    Public Sub Sort()        Dim a, b As T        If a.CompareTo(b) Then            'code        End If    End SubEnd Class 那么T所能取值的范围就大大减少了。我们不妨让用户在需要排序的时候,自行指定比较的依据,而不是强迫类型自己必须能够比较大小。改动成这样: Public Class MyContainer(Of T)    Public Sub Sort(ByVal compareHelper As Comparison(Of T))        Dim a, b As T        If compareHelper(a, b) Then            'code        End If    End SubEnd Class 这里,compareHelper就充当了辅助对象的功能。辅助对象是独立于类型T之外的,因此T不需要进行任何约束。而用户则必须为该功能提供正确的辅助对象。将辅助对象设置为委托是相当好的,这样用户可以只编写一个方法来规定辅助对性的功能(而不用编写一个完整的类)。C#用户甚至可以用匿名方法就地指定辅助对象的功能。.NET Framework为我们头提供了几个常用的泛型委托,都可以用作辅助对象的类型: System.Action(Of T) '是一个无返回值的方法,用于进行作用于一个T对象的动作 System.Comparison(Of T) '用于比较了两个T类型的对象 System.Converter(Of T, U) '用于指定将一个T对象转成U类型的规则 System.Predicate(Of T) '用于指定T类型的一个对象是否符合某项判断 当然,我们很容易就可以指定自己的辅助对象类型。不仅仅是委托,还可以是更加复杂的功能。用辅助对象代替约束,可以确保你的泛型类型有最大的应用范围,同时能让用户对特定的功能做深层次的定制。那什么时候用约束?当你的类确实只对某一类对象起作用,换句话说,你想要类型参数具有的功能贯穿整个泛型类的设计,那么约束就是更好的选择了。...[阅读全文]

posted @ | Feedback (3) | Filed Under [ 技术随笔 灵感记录 ]