posts - 16,  comments - 100,  trackbacks - 2
  2007年9月29日

  上篇文章中介绍了C# 3.0中比较简单的四个特性,分别是隐式类型化本地变量匿名类型隐式类型化数组,以及对象构造者,下面我将对C# 3.0中的较复杂,同时也是非常强大的几个特性进行介绍,供大家快速浏览。


第五个特性:集合构造者

  我们可以在声明数组的同时,为其指定初始值,方法是直接在数组声明的后面跟上初始值列表。这样就使数组的初始化工作变得简单,而对于我们自己创建的集合类型,就无法享受到与普通数组一样的待遇了,我们无法在创建自定义集合对象的同时,使用数组的初始化语法为其指定初始值。

  C# 3.0中加入的集合构造者特性,可使我们享受到与普通数组一样的待遇,从而在创建集合对象的同时为其指定初始值。为了做到这一点,我们需要让我们的集合实现ICollection<T>接口,在这个接口中,完成初始化操作的关键在于Add函数,当我使用初始化语法为集合指定初始值时,C#编译器将自动调用ICollection<T>中的Add函数将初始列表中的所有元素加入到集合中,以完成集合的初始化操作。使用示例如下:

   1:      class CollectionInitializer : AppRunner.AbstractApplication
   2:      {
   3:          class StringCollection : ICollection<string>
   4:          {
   5:              public void Add(string item)
   6:              {
   7:                  Console.WriteLine(item);
   8:              }
   9:   
  10:              // Other ICollection<T> Members
  11:          }
  12:   
  13:          public override void Run()
  14:          {
  15:              StringCollection strings = new StringCollection() { "Van's", "Brog", "Vicky" };
  16:          }
  17:      }

  在这个示例中,编译器会自动为strings对象调用Add方法,以将初始值列表中的所有元素加入到集合中,这里我们只是简单将初始值列表中的元素输出到控制台。


第六个特性:Lambda表达式

  C# 2.0中加入的匿名代理,简化了我们编写事件处理函数的工作,使我们不再需要单独声明一个函数来与事件绑定,只需要使用delegate关键字在线编写事件处理代码。

  而C# 3.0则更进一步,通过Lambda表达式,我们可以一种更为简洁方式编写事件处理代码,新的Lambda事件处理代码看上去就像一个计算表达式,它使用"=>"符号来连接事件参数和事件处理代码。我可以这样写:SomeEvent += 事件参数 => 事件处理代码;下面是完整的示例:

   1:      delegate T AddDelegate<T>(T a, T b);
   2:   
   3:      class LambdaExpression : AppRunner.AbstractApplication
   4:      {
   5:          public static event EventHandler MyEvent;
   6:   
   7:          public override void Run()
   8:          {
   9:              MyEvent += delegate(object s, EventArgs e)
  10:              {
  11:                  Console.WriteLine(s);
  12:              };
  13:   
  14:              MyEvent += (s, e) => { Console.WriteLine(s); };
  15:              
  16:              MyEvent(this, null);
  17:   
  18:              AddDelegate<string> add = (a, b) => a + b;
  19:   
  20:              Console.WriteLine(add("Lambda", "Expression"));
  21:          }
  22:      }

  在上面的例子中,分别使用了匿名代理和Lambda表达式来实现同样的功能,可以明显看出Lambda表达式的实现更为简洁。我们在使用Lambda表达式编写事件处理代码时,无需指明事件参数的类型,且返回值就是最后一条语句的执行结果。


第七个特性:扩展方法

  当我们需要对已有类的功能进行扩展时,我们通常会想到继承,继承已有类,然后为其加入新的行为。而C# 3.0中加入的扩展方法特性,则提供了另一种实现功能扩展的方式,我们可以在不使用继承的前提下实现对已有类本身的扩展,这种方法并不会产生新的类型,而是采用向已有类中加入新方法的方式来完成功能扩展。

  在对已有类进行扩展时,我们需将所有扩展方法都写在一个静态类中,这个静态类就相当于存放扩展方法的容器,所有的扩展方法都可以写在这里面。而且扩展方法采用一种全新的声明方式:public static 返回类型 扩展方法名(this 要扩展的类型 sourceObj [,扩展方法参数列表]),与普通方法声明方式不同,扩展方法的第一个参数以this关键字开始,后跟被扩展的类型名,然后才是真正的参数列表。下面是使用示例:

   1:      static class Extensions
   2:      {
   3:          public static int ToInt32(this string source)
   4:          {
   5:              return Int32.Parse(source);
   6:          }
   7:   
   8:          public static T[] Slice<T>(this T[] source, int index, int count)
   9:          {
  10:              if (index < 0 || count < 0 || index + count > source.Length)
  11:              {
  12:                  throw new ArgumentException();
  13:              }
  14:   
  15:              T[] result = new T[count];
  16:              Array.Copy(source, index, result, 0, count);    
  17:              return result;
  18:          }
  19:      }
  20:   
  21:      class ExtensionMethods : AppRunner.AbstractApplication
  22:      {
  23:          public override void Run()
  24:          {
  25:              string number = "123";
  26:              Console.WriteLine(number.ToInt32());
  27:   
  28:              int[] intArray = new int[] { 1, 2, 3 };
  29:   
  30:              intArray = intArray.Slice(1, 2);
  31:   
  32:              foreach (var i in intArray)
  33:                  Console.WriteLine(i);
  34:          }
  35:      }

  在上面的示例中,静态的Extensions类中有两个扩展方法,第一个方法是对string类的扩展,它为string类加入了名为ToInt32的方法,该方法没有参数,并返回一个int类型的值,它将完成数字字符向整数的转换。有了这个扩展方法之后,就可对任意string类的对象调用ToInt32方法了,该方法就像其本身定义的一样。

  第二个扩展方法是一个范型方法,它是对所有数组类型的扩展,该方法完成数组的切片操作。

  C# 3.0中的Linq表达式,就是大量运用扩展方法来实现数据查询的。


第八个特性:Linq查询表达式

  C# 3.0中加入的最为复杂的特性就是Linq查询表达式了,这使我们可直接采用类似于SQL的语法对集合进行查询,这就使我们可以享受到关系数据查询的强大功能。

  Linq查询表达式是建立在多种C# 3.0的新特性之上的,这也是我为什么最后才介绍Linq的原因。下面看一个例子:

   1:      class LinqExpression : AppRunner.AbstractApplication
   2:      {
   3:          public override void Run()
   4:          {
   5:              // 定义匿名数组persons, 并为其赋初值
   6:              var persons = new[] {
   7:                  new { Name="Van's", Sex=false, Age=22 },
   8:                  new { Name="Martin", Sex=true, Age=30 },
   9:                  new { Name="Jerry", Sex=false, Age=24 },
  10:                  new { Name="Brog", Sex=false, Age=25 },
  11:                  new { Name="Vicky", Sex=true, Age=20 }
  12:              };
  13:   
  14:   
  15:              /*
  16:                  执行简单Linq查询
  17:   
  18:                  检索所有年龄在24岁以内的人
  19:                  查询结果放在results变量中
  20:  
  21:                  results变量的类型与数组persons相同                
  22:              */
  23:              var results = from p in persons
  24:                            where p.Age <= 24
  25:                            select p;
  26:   
  27:              foreach (var person in results)
  28:              {
  29:                  Console.WriteLine(person.Name);
  30:              }
  31:   
  32:              Console.WriteLine();
  33:   
  34:   
  35:              // 定义匿名数组customers, 并为其赋初值
  36:              // 该数组是匿名类型的
  37:              var customers = new[] {
  38:                  new {
  39:                      Name="Van's", City="China", Orders=new[] {
  40:                          new {
  41:                              OrderNo=0,
  42:                              OrderName="C# Programming Language(Second Edition)",
  43:                              OrderDate=new DateTime(2007,9, 5)
  44:                          },
  45:                          new {
  46:                              OrderNo=1,
  47:                              OrderName="Head First Design Patterns(Chinese Edition)",
  48:                              OrderDate=new DateTime(2007,9,15)
  49:                          },
  50:                          new {
  51:                              OrderNo=2,
  52:                              OrderName="ASP.NET Unleashed 2.0(Chinese Edition)",
  53:                              OrderDate=new DateTime(2007,09,18)
  54:                          },
  55:                          new {
  56:                              OrderNo=3,
  57:                              OrderName="The C++ Programming Langauge(Special Edition)",
  58:                              OrderDate=new DateTime(2002, 9, 20)
  59:                          }
  60:                      }
  61:                  },
  62:                  new {
  63:                      Name="Brog", City="China", Orders=new[] {
  64:                          new {
  65:                              OrderNo=0,
  66:                              OrderName="C# Programming Language(Second Edition)",
  67:                              OrderDate=new DateTime(2007, 9, 15)
  68:                          }
  69:                      }
  70:                  },
  71:                  new {
  72:                      Name="Vicky", City="London", Orders=new[] {
  73:                          new { OrderNo=0,
  74:                              OrderName="C++ Programming Language(Special Edition)",
  75:                              OrderDate=new DateTime(2007, 9, 20)
  76:                          }
  77:                      }
  78:                  }
  79:              };
  80:   
  81:   
  82:              /*
  83:                  执行多重Linq查询
  84:   
  85:                  检索所在城市为中国, 且订单日期为2007年以后的所有记录
  86:                  查询结果是一个匿名类型的数组
  87:                  其中包含客户名, 订单号, 订单日期, 订单名四个字段
  88:              */
  89:              var someCustomers = from c in customers
  90:                                  where c.City == "China"
  91:                                  from o in c.Orders
  92:                                  where o.OrderDate.Year >= 2007
  93:                                  select new { c.Name, o.OrderNo, o.OrderDate, o.OrderName };
  94:   
  95:   
  96:              foreach (var customer in someCustomers)
  97:              {
  98:                  Console.WriteLine(
  99:                      customer.Name + ", " + customer.OrderName + ",  " +
 100:                      customer.OrderDate.ToString("D")
 101:                  );
 102:              }
 103:          }
 104:      }

  从上面的例子中,我们可以看到Linq查询的强大特性,它允许我们进行简单查询,或者进行更为复杂的多重连接查询。且查询的结果还可以是自定义的匿名类型。

  以上是对C# 3.0中新增的八大特性的简要介绍,如果想了解更为深入的内容,可查看C# 3.0的官方规范。

 

相关文章:C#3.0 新特性速览(1)

posted @ 2007-09-29 13:52 van‘s 阅读(2636) | 评论 (18)编辑
  2007年9月26日

  微软最近的动作频繁,C#2.0规范才刚推出不久,我还没来的及完全消化C#2.0中的所有新特性,而今又推出了C#3.0,在短短几年中,微软就对C#进行了两次大的升级,为C#加入了许多新的特性,从而使C#变得更加强大也更加现代了。下面我就把C#3.0中的新特性的要点列出来,以供大家快速浏览。


第一个特性:隐式类型化本地变量

  这个特性非常简单,有些JavaScript的影子,我们可以统一使用使用"var"关键字来声明局部变量,而不再需要指明变量的确切类型了,变量的确切类型可通过声明变量时的初始值推断出来。这样一来,可以大大简化我们声明局部变量的工作量了,下面是一个例子:

   1:      class LocalVariables : AppRunner.AbstractApplication
   2:      {
   3:          public override void Run()
   4:          {
   5:              var intValue = 5;
   6:              var stringValue = "This is a string";
   7:              var customClass = new LocalVariables();
   8:              var intArray = new int[3] { 1, 2, 3 };
   9:   
  10:              foreach (var value in intArray)
  11:                  Console.WriteLine(value);            
  12:          }
  13:      }

上面的代码将被解析成:

   1:      class LocalVariables : AppRunner.AbstractApplication
   2:      {
   3:          public override void Run()
   4:          {
   5:              int intValue = 5;
   6:              string stringValue = "This is a string";
   7:              LocalVariables customClass = new LocalVariables();
   8:              int[] intArray = new int[3];
   9:   
  10:              foreach (int value in intArray)
  11:                  Console.WriteLine(value);            
  12:          }
  13:      }

  要特别注意的是,由于变量的类型是通过变量初始值推断而来的,所以在声明变量的同时必需为变量指定初始值。并且,变量并不是没有类型的,变量一旦初始化之后,类型就确定下来了,以后就只能存储某种类型的值了,比如上面的stringValue的类型经推断为string,所以该变量就只能保存string类型的值了。


第二个特性:匿名类型 

  有些时候我们需要临时保存一些运算的中间结果,特别是当这些中间结果是由多个部份组成时,我们常常会去声明一个新的类型,以方便保存这些中间结果。表面上看起来这很正常,而细想之后就会发现,这个新类型只服务于这个函数,其它地方都不会再使用它了,就为这一个函数而去定义一个新的类型,确实有些麻烦。

  现在,C#3.0中的匿名类型特性就可以很好的解决上面提到的问题,通过匿名类型,我们可以简单使用new { 属性名1=值1, 属性名2=值2, ..... , 属性名n=值n }的形式直接在函数中创建新的类型,看下面这个例子:

   1:      class AnonymousType : AppRunner.AbstractApplication
   2:      {
   3:          public override void Run()
   4:          {
   5:              var anonymousType1 = new {
   6:                  CardNumber = "10001", Name = "van's", Sex = true
   7:              };
   8:   
   9:              Console.WriteLine(anonymousType1.CardNumber);
  10:              Console.WriteLine(anonymousType1.Name);
  11:   
  12:              var anonymousType2 = new {
  13:                  CardNumber = "10002", Name = "martin", Sex = true
  14:              };
  15:   
  16:              anonymousType2 = anonymousType1;
  17:          }
  18:      }

  在新类型中只能有字段成员,而且这些字段的类型也是通过初值的类型推断出来的。如果在声明新的匿名类型时,新类型的字段名、顺序以及初始值的类型是一致的,那么将会产生相同的匿名类型,所以上例中anonymousType1和anonymousType2的类型是相同的,自然能进行anonymousType2=anonymousType1的赋值。


第三个特性:
隐式类型化数组

  这个特性是对隐式类型化本地变量的扩展,有了这个特性,将使我们创建数组的工作变得简单。我们可以直接使用"new[]"关键字来声明数组,后面跟上数组的初始值列表。在这里,我们并没有直接指定数组的类型,数组的类型是由初始化列表推断出来的。

    1:      class AnonymousTypeArray : AppRunner.AbstractApplication
   2:      {
   3:          public override void Run()
   4:          {
   5:              var intArray = new[] { 1, 2, 3, 4, 5 };
   6:              var doubleArray = new[] { 3.14, 1.414 };
   7:              var anonymousTypeArray = new[] {
   8:                  new { Name="van's", Sex=false, Arg=22 },
   9:                  new { Name="martin", Sex=true, Arg=23 }
  10:              };
  11:   
  12:              Console.WriteLine(intArray);
  13:              Console.WriteLine(doubleArray);
  14:              Console.WriteLine(anonymousTypeArray[0].Name);
  15:          }
  16:      }

  上面的代码中,anonymousTypeArray变量的声明同时运用了隐式类型化数组和匿名类型两种特性,首先创建匿名类型,然后再初始值列表,推断出数组的确切类型。


第四个特性:对象构造者

  我们在声明数组时,可以同时对其进行初始化,这样就省去了很多麻烦,但是在创建类的对象时,这招可就不灵了,我们要么调用该类的构造函数完成对象的初始化,要么就手工进行初始化。这两种方法都不太方便,使用构造函数来对对象进行初始化时,我们为了某种灵活性,可能需要编写构造函数的多个重载版本,实在是麻烦。

  C#3.0中加入的对象构造者特性,使得对象的初始化工作变得格外简单,我们可以采用类似于数组初始化的方式来初始化类的对象,方法就是直接在创建类对象的表达式后面跟上类成员的初始化代码。具体示例如下:

   1:     class Point
   2:     {
   3:          public int X { get; set; }
   4:          public int Y { get; set; }
   5:   
   6:          public override string ToString()
   7:          {
   8:              return "(" + X.ToString() + ", " + Y.ToString() + ")";
   9:          }
  10:      }
  11:   
  12:      class Rectangle
  13:      {
  14:          public Point P1 { get; set; }
  15:          public Point P2 { get; set; }
  16:   
  17:          public Rectangle()
  18:          {
  19:              P1 = new Point();
  20:              P2 = new Point();
  21:          }
  22:   
  23:          public override string ToString()
  24:          {
  25:              return "P1: " + P1 + ", P2: " + P2;
  26:          }
  27:      }
  28:   
  29:      class ObjectBuilder : AppRunner.AbstractApplication
  30:      {
  31:          public override void Run()
  32:          {
  33:              Point thePoint = new Point() { X = 1, Y = 2 };
  34:              Console.WriteLine("Point(X, Y) = {0}", thePoint);
  35:   
  36:              Rectangle theRectangle = new Rectangle() { 
  37:                  P1 = { X = 1, Y = 1 }, P2 = { X = 100, Y = 200 } 
  38:              };
  39:              Console.WriteLine(theRectangle);
  30:          }
  41:      }

  我们在定义Point类的X和Y属性时,只须写上该属性的get和set访问器声明,C#编译器会自动为我们生成默认的get和set操作代码,当我们需要定义简单属性时,这个特性非常有用。

  我们以new Point() { X = 1, Y = 2 }语句,轻松的完成了对Point类的初始化工作。在创建类的对象时,我们可以按照需要去初始化类的对象,只要在类的创建表达式后跟上要初始化属性的列表即可,且可以只对需要初始化的属性赋初值,而无需把所有属性的初始值都写上去。

  在theRectangle对象的初始化表达式中,我们首先对P1属性进行初始化,然而P1属性也是一个自定义的类型,所以P1属性的初始化是另一个类型(Point)的初始化表达式,我们可以这样的方式来对更加复杂的类型进行初始化。

  未完待续.........

相关文章:C#3.0 新特性速览(2)

posted @ 2007-09-26 00:59 van‘s 阅读(3369) | 评论 (25)编辑
  2007年9月17日

  今天,终于拿到了《Head First设计模式》的简体中文版了!

  从得知有这么一本好书,到等待中文译本的出版,再到今天拿到这本书,一切都是那么的漫长。

  早在今年2月份,就从UMLChina上看到这样一条令我兴奋的消息,Amazon书店头牌书:《Head First设计模式》大陆译本很快就要由中国电力出版社出版了。大陆译本由UMLChina在蔡学镛台湾译本基础上改编而成。

  可这条消息过后,很长一段时间里,都没有再听到此书的简体中文译本的消息了,与UMLChina联系后才得知,这本书的简体中文译本早在年前就已交给中国电力出版社了,只是出版社那边一直没有消息,而中国电力出版社的官网也没有任何关于此书的消息,就好像根本就没这么一回事。

  直到今年9月,才在China-Pub上看到了这本书的中文译本,于是立刻订了一本,今天终于拿到手了!

clip_image0022

  这是一本讲叙设计模式的经典巨著,该书获得了2005年第15届Jolt震撼大奖,由此可见这本书的权威性了。

  O'REILLY公司的Head First系列图书的特点是,图文并茂,内容生动有趣,有相当高的可读性,《Head First设计模式》当然也不例外,就连《设计模式》的作者之一Erich Gamma都这样说:“我昨天收到这本书,在回家的路上开始读,简直欲罢不能,于是我把书带到健身房,我一边运动,一边阅读,脸上堆满笑容。这真是太酷了!不但有趣、涵盖许多基础知识、而且观点正确,真的让我印象深刻。”

clip_image0041
我又多了一本经典图书

  在翻阅《Head First设计模式》的出版信息时,发现这本书的英文版早在2004年就已经出版,而简体中文译本到现在才出版,整整晚了三年。要知道,软件业的发展是如此之快,而我们现在看的却还是别人三年前写的东西 :(

posted @ 2007-09-17 01:50 van‘s 阅读(1165) | 评论 (10)编辑
  2007年9月12日

  我是2002年开始学的C++,当时的学习资料是由C++的发明者Bjarne Stroustrup所著的《C++程序设计语言(中文特别版)》,所以在权威性上,这本书是其它任何同类书籍所无法比拟的,有了读这本书的经历后,让我明白了这样一个道理:选一本好书会使我们少走很多弯路。也就是因为这本书,真正把我带进了程序设计的殿堂。

  在紧接的2004年我又学起了Java,而学习资料是《Java编程思想(第3版)》,个人感觉该书可以当作学习Java语言的标准教材,内容深入浅出,同样非常权威,而深度和广度就更不用说了。现在这本书已经出到了第4版,主要是加入了对Java 5的新特性介绍。

  在这之后,我又开始研究设计模式,其实这纯属巧合,一次在图书馆里找书的时候,无意间发现了一本《敏捷软件开发-原则、模式与实践》,感觉名字比较特别,就翻了几页,看到这本书的排版和印刷都很漂亮,就借了回去。我当时对什么是敏捷软件开发根本就一无所知,看了这本书之后,才知道什么是敏捷软件开发,什么是XP,什么是设计模式,以及什么是面向对象的设计原则。这本书使我真正了解了什么是面向对象,如何使用面向对象的方式构建出"美"的软件,我也很欣赏作者在书中对软件之美所作出的诠释!让我明白:软件开发也是一门艺术,就像是艺术家创作出美的东西一样,软件开发也同样可以创造出美的东西来,只要足够用心!

  而到了2005年,由于.NET越来流行,我又开始学起了C#,而由于当时并没有找到一本像《C++程序设计语言》或《Java编程思想》这样权威的教材,所以干脆就拿微软的C#语言规范作为教材,糊里糊涂的学了起来,所以学的很不系统也很不全面。

  参加工作后,由于教学的需要,要为软件开发班的学生选一本C#的教材,找了半天,最终选中了《C#入门经典(第3版)》,理由是比较适合作为入门教材(主要是比较简单),但这本书的内容不够深入。

  为什么就没有一本于C#的权威教材呢?难道没人关心C#吗?

  直到2007年的8月,我才发现了由电子工业出版社引进的一本名为《C#编程语言(第2版)》的C#教程,作者是C#语言的构架师Anders Hejlsberg和C#设计团队的成员,所以在权威性方面应该是没得说的。

  用C#已经一段时间了,在.NET平台上也用C#写过一些项目,但却从来没有像使用C++或Java那样的知根知底的感觉,没安全感,所以觉得还应该再系统的学习一遍,以对C#有个比较全面而深入的了解,为了提高兴趣,特意买了本英文版的,这样也可以锻炼自己的英文阅读能力。(其实主要是因为买这本书的时候并没有出中文版,中文版是最近才出的)

  随后,我又看了《ASP.NET揭密(第2版)》,感觉这本书写的很全面,且作者笔风流畅,看起来也很流畅。应该算是ASP.NET的标准教材吧。

  我看过的书还有《Visual C++.NET 技术内幕(第6版)》(VC的权威参考书)、《Windows图形编程》(美籍华人的经典著作)、《Professional JavaScript™ for Web Developers(英文版)》(是我看过是讲解JavaScript最全面的一本书了)、《UML2 工具箱》、《重构-改善即有代码的设计》(重构方面的巨著)、《人件》(学会怎样和老板及同事相处)、《JOEL说软件》(软件业的经典小品类书籍)、《代码大全》(讲叙软件开发的方方面面,所有程序员必备的参考书)、《使用Ant进行Java开发》(写的很好,看起来很流畅,是学习自动化构建的权威参考书)、《Ajax in Action》、《.NET设计规范》、《CSS禅意花园》(可以很好的纠正我们滥用HTML标记的坏习惯,并学习如何去创造美的东西)、《Spring专业开发指南》(学习Spring的权威教材)、《Hibernate Quickly》、《Programming Ruby》(时下流行的Ruby语言的权威参考书)、《单元测试之道-C#版》、《80x86汇编语言程序设计》(呵呵,可以了解计算机的工作原理)、《MS-DOS 6.22》(这是我的第一本计算机类图书,这本书完整的介绍了MS-DOS的方方面面)、《数据结构与算法:C++版》(翻的不太好,像是盗版的)

 

  有了读这些书经历,使得我对软件开发有了比较全面的了解,以及对计算机学科体系的总体认识,在遇到问题时,总能运用所学知识找到解决方案,也正是因为这些书,使我越来越热爱这个行业,并立志要在这个行业中干出一番事业来。

posted @ 2007-09-12 18:40 van‘s 阅读(318) | 评论 (10)编辑
  2007年8月12日

  记得在大学时,我在物质上的最大愿望,就是拥有一台属于自己的本本,可是家人并不赞同我的想法,说笔记本太容易被偷,而且也太娇贵。可我不死心,硬是找来大堆理由来与家人理论,经过和家人的一番思想斗争后,得出的结论是同意给我买一台旧本本,这样丢了也就不心疼了。

  就这样,我便有了大学时的第一台本本,一台二手的HITACHI(日立)12寸银白色本本,是2005年1月份买的,当时花了2200,配置偏低,不过用它写写程序上上网,还是不成问题的。虽然是二手本本,但我还是爱如珍宝,小心翼翼的使用着。天天搂着它,吃饭睡觉都不离身,室友们开玩笑的说,这台本本就像我的小老婆一样。

  可好景不长,还没到一年,本本就出事了,本本的屏幕在一次意外中被我给压破了,屏幕中出现了一道长长的裂痕,没法正常使用了,拿去找人修,维修的人说得换块屏幕,而且换屏花的钱和再买一台差不多。听到这番话后,我的心就像被针给扎了,不知道有多难受。回到学校后,室友竟然发现我的头上多了根白头发。

  后来,家人又给我弄了台本本,也是旧的,而且年代久远,是1998年产的NEC的10寸本本,配置很低,CPU是奔腾MMX的,频率只有266MHz,内存96MB,硬盘只有3G,如果在1998年,这台本本肯定很值钱,可是在2006年,这本本只能用来听听歌,连上个QQ都很慢,根本没法用,不过我也没什么可说的,谁叫我当初没好好爱护好之前的那台本本呢,也只能这样将就着用了,等以后自己能赚钱了,再买台好的。

  如今,我已经工作一年多了,已有能力为自己买一台好本本,所以就开始在网上选本本了。

  一开始,我看中了HP Compaq的V3323TU,当时的报价为7600块,我之所以会看中这款,主要是因为它的外观,纯黑色机身,再加上是钢琴烤漆的,外观十分靓丽,而且就7600块的价格而言,性价比应该也是很高的。

127563-34 
HP Compaq V3323TU

  而在配置方面,这款机器的CPU是Intel Core T5300,频率为1.73GHz,FSB只有533MHz,1G DDRII 667MHz的内存,5400转的80G硬盘,COMBO光驱,10/100M网卡,内置Intel PRO 3945A/B/G无线网卡,就这样的配置,对于我应该是够用的。

  我原本打算就买这款了,可突然想起一个之前从没有考虑过的问题,这本本耐不耐用?因为之前有了一次本本屏幕被压破的经历,所以这次买本本一定要注意这个问题,于是上网查了查,结果发现,IBM的本本比较耐用,而IBM的本本都很贵,大部份IBM的本本都在1万块钱以上,差不多可以买两台HP Compaq的本本了。

  为什么IBM的本本就这么贵呢?它贵在哪呢?为了弄清楚这些问题,我又上网查了大量IBM本本的资料,后来才发现IBM本本和其它本本的不同之处,就我个人认为,最具吸引力的应该是下面这几个特性:

  1. IBM的本本的顶盖采用的是铝镁合金材料,所以非常坚固,可以很好的保护液晶显示屏。(这是我最看中的地方)
  2. IBM的本本特有APS硬盘保护技术,可以有郊的减少振动对硬盘的伤害。
  3. IBM的本本特有镁制防滚架,可以有郊减少外部冲击对机内部件的伤害。
  4. IBM的本本特有的三级散热系统,可以有郊控制机身的温度。

  就是因为有了这些特性,IBM的本本才能卖到这么贵。经过一番思想斗争后,我还是说服了自己,决定选择IBM的本本,因为IBM本本的这些特性太吸引我了,特别是它的铝镁合金材料的顶盖,这样我就不用担心本本屏幕再被压坏了。

  竟然已经下定决心选择IBM的本本了,那么下一步就是去选择具体型号了,到IBM的卖场后,我第一个看中的就是一款宽屏的本本,因为宽屏本本看电影很爽,而且宽屏本本的可视面积也比普屏本本高出20%,后来看了看型号,得知这款的型号为ThinkPad z61t 9441MK5,而且配置方面我也很满意,这款机器的CPU是Intel Core 2 T5600,频率为1.83GHz,FSB为667MHz,512 DDRII 667MHz的内存, 5400转的80G硬盘,COMBO光驱,10/100/1000M网卡,内置Intel PRO 3945A/B/G无线网卡,内置蓝牙,内置红外,内置30万像素摄像头。

131043
ThinkPad z61t 9441MK5

  我是和一个朋友一起去买的,我不太会还价,所以还价的工作就由他一个人负责了,经过一伦伦舌战后,最后还到12000块,带票,而且还加了块512MB的内存,当时的日期为2007年5月25日。

  机器买回去后,我立刻装了Windows Vista,系统运行起来还算流畅,得到了3.1分,因为没有独立显卡,所以系统的瓶颈在于3D商务和游戏图形性能。

 新图片
Vista系统评分

 

  本本已经用了快两个月了,总体感觉很好,下面总结一下我个人对这款本本的看法:

  1. 键盘的手感很好,基本上和台式机差不多。
  2. 本本很小巧,不像是14寸的本本,可能是宽屏的缘故吧,显得小,而且厚度控制的也很好,重量只有2.1公斤。
  3. 屏幕效果还可以,而且宽屏也可以显示更多的内容。但可惜不是镜面的,容易脏。
  4. 音响效果不错,特别是中音部分表现的很好,可惜就是音量小了点。

 

  我要特别指出的是,想要流畅运行Windows Vista的话,内存至少要配1G,但是想要在Vista上运行一些大型软件的话,如Visual Studio、Photoshop,那么就要配2G的内存了,因为光是Vista就要用掉600MB~800MB的内存,所以想要在Vista上流畅的工作的话,1G的内存是不够用的。

 

  最后贴几张我自己拍的本本的照片。

PIC00005 PIC00006
PIC00007 PIC00008
PIC00009 PIC00010
PIC00011 PIC00012
PIC00013 PIC00014
PIC00015 PIC00018

 

posted @ 2007-08-12 18:24 van‘s 阅读(306) | 评论 (11)编辑
  2007年7月27日

刚装上了Windows Live Writer,现发篇文章测试一下。
 
Code test
   1:  using System;
   2:   
   3:  class Program
   4:  {
   5:      static void Main(string[] args)
   6:      {
   7:          Console.WriteLine("Hello world from C#!");
   8:      }
   9:  }
 
 
Text test
Normal, Bold, Italic, Underline
 
 
Blockquote test
This is a text
 
Image test
IMG0654A 
 
Link test
My Blog Address

 

Table test

Tab1 Tab2

 in table image->

IMG0655A
Tab3 Tab4

 

Map test


posted @ 2007-07-27 13:02 van‘s 阅读(90) | 评论 (0)编辑
  2007年7月23日

     前段时间,用AJAX+VML写了一个Web在线会议平台,觉得挺有意思的,现在把它拿上来与大家分享 ^_^

     这是一个类似于NetMeeting的在线会议平台,但特别之处在于,WebMeeting不需要安装额外的软件,只要有IE就能使用,这样一来,使用者只要能够上网,就能进行在线会议。

     WebMeeting还只是一个概念,目前只有电子白板和即时消息发送的功能。WebMeeting的界面是仿flickr风格的,所以非常简洁。如下图所示:


                                  WebMeeting的界面 
 

功能介绍:
     电子白板:可多人同时进行白板操作,且每个人都可以看到操作过程。
     在线交流:可进行简单的消息发送。


使用方法:
     使用者只要在浏览器中输入WebMeeting所在的WEB服务器地址,就能进行Web在线会议了,多人可同时使用白板绘制图形,发送文本消息,而这些动作都将会反映在每个使用者的屏幕上,如下图所示:


                  用户A                                                                       用户B
 

WebMeeting的工作原理:
     WebMeeting是用AJAX+VML实现的,VML是作为表示层用来进行白板的绘制,故WebMeeting目前只能在IE上运行,而用户操作的反馈则是通过AJAX进行传递的。


                                                         系统运行流程图 


     通常情况下,使用AJAX可实现浏览器端与服务器端的异步通信,特别是有了AjaxPro.NET后,更可以非常方便的以同步或异步的方式去调用服务器端的方法,但由于WebMeeting即需要从浏览器端异步调用服务器端方法来完成动作的反馈(即浏览器端把用户的动作发送到服务器),且服务器又需要完成用户动作的分发(即服务器接收到用户的反馈后把动作分发到各浏览器端),也就是说,需要双向的AJAX调用:浏览器端调用服务器端的函数以及服务器端调用浏览器端的函数。

     要从浏览器端调用服务器端的方法,AjaxPro.NET可很好的应付,可以利用JavaScript轻松的调用服务器端方法,但是反过来,若想从服务器端调用浏览器端的方法的话,就不是那么容易了,因为AjaxPro.NET并没有提供这个功能。

     从本质上讲,B/S结构的应用程序天生就是无状态的,所以就没有办法从服务器端直接调用浏览器端的方法,因为所有请求都是单方向的,只能从浏览器端向服务器发出请求。

     为了使服务器调用浏览器端方法成为可能,可以采用控制反转的方法,可按照如下步骤进行:
     a)   当从服务器端调用浏览器端方法时,并不真正的去调用浏览器端方法,而是把调用信息暂时保存在服务器端的“调用信息”队列中。
     b)   在浏览器端安排一个“查询进程”,让它每隔一段时间调用服务器端的“调用查询”函数,该函数会从服务器端的“调用信息”队列中提取出一条调用信息,然后作为返回值返回给浏览器端的“查询进程”。
     c)   浏览器端“查询进程”分析服务器端返回的查询结果,然后代理服务器端调用,最后把浏览器端方法执行的结果传回给服务器端“调用进程”。

     这样一来,就可以非常方便的从服务器端调用浏览器端的方法,就像下面这样:

// Page 为浏览器端方法调用器的启动页面
ClientSideMethodCaller caller = new ClientSideMethodCaller(Page);

// clientMethodName:        浏览器端方法名
// param1,param2,………      调用参数
// returnValueReader          返回值阅读器
caller.Call(“clientMethodName”, param1, param2, ………, returnValueReader);

     以上就是对WebMeeting的完整介绍,可能有点长,但希望能给想写这类应用的朋友带来一些灵感。

     另附上WebMeeting的源代码及说明文档:

     WebMeeting下载
     WebMeeting说明文档

posted @ 2007-07-23 03:08 van‘s 阅读(376) | 评论 (9)编辑
  2007年4月20日

     看到我的Blog,有没有让你联想到Flickr的界面?如果还有些感觉,那么我的幸苦总算是没有白费 ^_^

     自从用过Flickr之后,我就开始喜欢上像Flickr这样简洁明了的界面风格了,给人一种非常干净的感觉,这可能就是所谓的Web2.0的网络应用风格吧。
     于是突发奇想,打算把我的Blog也改造成Flickr风格的,也沾一点Flickr的光。经过一潘折腾,把主色调改成了蓝色+红色,再加上淡灰色的左导航栏。呵呵,有点Flickr的意思了吧!

     这里还要特别感谢博客园的设计者,使得界面风格的改动变得如此的简单了。

posted @ 2007-04-20 18:52 van‘s 阅读(107) | 评论 (5)编辑
  2007年4月14日


     学习敏捷软件开发方法已经有一段时间了,也试验性的应用该方法写过一些小的程序,有了一些自己对该方法的理解,但一直没有写过关于这方面的文章,最近由于教学的需要,要准备一份关于敏捷软件开发方法的完整资料,这次正好借此机会,把我在应用敏捷方法过程中的心得体会,写成系列文章,一来是为了与大家分享,再者也好把它整理成完整的文档,方便教学。


在该系列文章中,我主要会写以下几方面的内容:

一、什么是敏捷软件开发方法
     作为开遍,这里主要是对敏捷软件开发方法的综合性介绍,对敏捷软件开发方法的一系列组成部的概要性说明。

二、测试驱动开发
     在这里,主要介绍什么是测试驱动开发,以及说明为什么需要这种编写代码的方式,并与传统编码方式做了一些比较。

三、结对编程
     结对编程,是一种全新的团队协作方法,软件的每部分都是在两个人的协作下完成的,在这里,对结对编程做了一个系统的介绍,并讨论了这种方法与传统方法的不同之处。

四、重构
     重构是敏捷软件开发方法中用来改善即有代码质量的手段,通过一系列的方法,能够在不改变系统外在行为的前提下改善代码的质量。由于重构的内容很多,我在里只会简单的介绍一些重构的最基本手法。

六、应用案例
     这里主要向大家展示采用敏捷软件开发方法完成的几个小的案例,我会尽量真实的还原当时的场景,给大家一个对敏捷软件开发方法的完整体验。


     最后,由于本人水平有限,如果文章有什么不得当的地方,欢迎大家指正。

posted @ 2007-04-14 18:29 van‘s 阅读(349) | 评论 (1)编辑
  2007年1月4日
     摘要: 京城,振威镖局,镖局的废墟上..天空晴朗,白云朵朵,然而镖局废墟上空似乎有无尽的悲哀..

约1500人,清一色是浅黄色武士装,腰挎刀,手牵VS杀手犬的彪形大汉,阵形甚是整齐..本该是豪情壮志的汉子,但是此刻,每个人脸上都隐约可见泪痕,如此英雄好汉,能让他们掉眼泪,必定是遇到了极大的伤心事和挫折..领头一人,双目泪光闪烁,脸色苍白,双拳紧握,牙关紧咬,仰面向天,片刻后,对着西边凤鸣山大喊道:"我丁一刀,如不报此仇,誓不为人!",此声悲壮,伤心,义愤之情也感染了在场的众好汉,大家齐声道:  阅读全文
posted @ 2007-01-04 17:14 van‘s 阅读(74) | 评论 (1)编辑