ASP.NET是微软最新推出的新型体系结构.NET框架的一部分,它为构造新一代动态网站和基于网络的分布式应用提供了强有力的支持。与以前的 Web 开发模型相比,ASP.NET 提供了许多重要的优点例如: 简易性;安全性;可管理性等。而且与基于过程的ASP页面技术相比,面向对象技术在ASP.NET中得到了完全实现。用传统ASP技术建立的Web应用实例中,在页面中同时实现显示,业务逻辑和流程控制,这从工程化的角度考虑,它有许多不足之处。用户界面承担着向用户显示问题模型和与用户进行操作和I/O交互的作用。用户希望保持交互操作界面的相对稳定,但更希望根据需要改变和调整显示的内容和形式。在.NET框架下ASP.NET技术结合MVC设计模式很好地解决了上述问题。
1 MVC设计模式简介
MVC由Trygve Reenskaug提出,首先被应用在SmallTalk-80环境中,是许多交互和界面系统的构成基础。MVC结构是为那些需要为同样的数据提供多个视图的应用程序而设计的,它很好的实现了数据层与表示层的分离。MVC作为一种开发模型,通常用于分布式应用系统的设计和分析中,以及用于确定系统各部分间的组织关系。对于界面设计可变性的需求,MVC(Model-View-Controller)把交互系统的组成分解成模型、视图、控制器三种部件。
视图部件把表示模型数据及逻辑关系和状态的信息以特定形式展示给用户。它从模型获得显示信息,对于相同的信息可以有多个不同的显示形式或视图。
控制器部件是处理用户与软件的交互操作的,其职责是控制提供模型中任何变化的传播,确保用户界面于模型间的对应联系;它接受用户的输入,将输入反馈给模型,进而实现对模型的计算控制,是使模型和视图协调工作的部件。
模型部件保存由视图显示,由控制器控制的数据;它封装了问题的核心数据、逻辑和功能的计算关系,它独立于具体的界面表达和I/O操作。
模型、视图与控制器的分离,使得一个模型可以具有多个显示视图。如果用户通过某个视图的控制器改变了模型的数据,所有其它依赖于这些数据的视图都应反映到这些变化。因此,无论何时发生了何种数据变化,控制器都会将变化通知所有的视图,导致显示的更新。这实际上是一种模型的变化-传播机制。模型、视图、控制器三者之间的关系和各自的主要功能,如图1所示。
2 MVC设计模式的实现
ASP.NET提供了一个很好的实现这种经典设计模式的类似环境。开发者通过在ASPX页面中开发用户接口来实现视图;控制器的功能在逻辑功能代码(.cs)中实现;模型通常对应应用系统的业务部分。在ASP.NET中实现这种设计而提供的一个多层系统,较经典的ASP结构实现的系统来说有明显的优点。将用户显示(视图)从动作(控制器)中分离出来,提高了代码的重用性。将数据(模型)从对其操作的动作(控制器)分离出来可以让你设计一个与后台存储数据无关的系统。就MVC结构的本质而言,它是一种解决耦合系统问题的方法。
2.1 视图
视图是模型的表示,它提供用户交互界面。使用多个包含单显示页面的用户部件,复杂的Web页面可以展示来自多个数据源的内容,并且网页人员,美工能独自参与这些Web页面的开发和维护。
在ASP.NET下,视图的实现很简单。可以像开发WINDOWS界面一样直接在集成开发环境下通过拖动控件来完成页面开发本。本文中介绍每一个页面都采用复合视图的形式即:一个页面由多个子视图(用户部件)组成;子视图可以是最简单HTML 控件、服务器控件或多个控件嵌套构而成的Web自定义控件。页面都由模板定义,模板定义了页面的布局,用户部件的标签和数目,用户指定一个模板,平台根据这些信息自动创建页面。针对静态的模板内容,如页面上的站点导航,菜单,友好链接,这些使用缺省的模板内容配置;针对动态的模板内容(主要是业务内容),由于用户的请求不同,只能使用后期绑定,并且针对用户的不同,用户部件的显示内容进行过滤。使用由用户部件根据模板配置组成的组合页面,它增强了可重用性,并原型化了站点的布局。
视图部分大致处理流程如下:首先,页面模板定义了页面的布局;页面配置文件定义视图标签的具体内容(用户部件);然后,由页面布局策略类初始化并加载页面;每个用户部件根据它自己的配置进行初始化,加载校验器并设置参数,以及事件的委托等;用户提交后,通过了表示层的校验,用户部件把数据自动提交给业务实体即模型。
这一部分主要定义了WEB页面基类PageBase;页面布局策略类PageLayout,完成页面布局,用于加载用户部件到页面;用户部件基类UserControlBase即用户部件框架,用于动态加载检验部件,以及实现用户部件的个性化。为了实现WEB应用的灵活性,视图部分也用到了许多配置文件例如:置文件有模板配置、页面配置、路径配置、验证配置等。
2.2 控制器
为了能够控制和协调每个用户跨越多个请求的处理,控制机制应该以集中的方式进行管理。因此,为了达到集中管理的目的引入了控制器。应用程序的控制器集中从客户端接收请求(典型情况下是一个运行浏览器的用户),决定执行什么商业逻辑功能,然后将产生下一步用户界面的责任委派给一个适当的视图组件。
用控制器提供一个控制和处理请求的集中入口点,它负责接收、截取并处理用户请求;并将请求委托给分发者类,根据当前状态和业务操作的结果决定向客户呈现的视图。在这一部分主要定义了HttpReqDispatcher(分发者类)、HttpCapture(请求捕获者类)、Controller(控制器类)等,它们相互配合来完成控制器的功能。请求捕获者类捕获HTTP请求并转发给控制器类。控制器类是系统中处理所有请求的最初入口点。控制器完成一些必要的处理后把请求委托给分发者类;分发者类分发者负责视图的管理和导航,它管理将选择哪个视图提供给用户,并提供给分发资源控制。在这一部分分别采用了分发者、策略、工厂方法、适配器等设计模式。
为了使请求捕获者类自动捕获用户请求并进行处理,ASP.NET 提供低级别的请求/响应 API,使开发人员能够使用 .NET 框架类为传入的 HTTP 请求提供服务。为此,必须创作支持 System.Web.IHTTPHandler 接口和实现 ProcessRequest() 方法的类即:请求
[转载]感悟测试驱动开发
Filed Under (默认分类) by 刘 鹏 on 30-08-2006
软件开发方法学的泰斗Kent Beck先生最为推崇"模式、极限编程和测试驱动开发"。在他所创造的极限编程(XP)方法论中,就向大家推荐"测试先行"这一最佳实践,并且还专门撰写了《测试驱动开发》一书,详细说明如何实现。测试驱动开发是极限编程的重要特点,它以不断的测试推动代码的开发,从而实现既简化代码,又保证质量的目标。
一看到"测试先行"、"测试驱动"这样的名字,就深深地激起了我强烈的好奇心,开始了自己的探索之旅..
心灵震憾
一段时间的学习,让我的内心受到了深深的震撼。我们原来的方法居然如此的笨我面对测试先行这一名字时,当时最大的疑问就是"程序都还没有写出来, 测试什么呀!"。后来一想,其实这是一个泥瓦匠都明白的道理,却是自己在画地为牢。我们来看看两个不同泥瓦匠是
如何工作的吧:
工匠一:先拉上一根水平线,砌每一块砖时,都与这根水平线进行比较,使得每一块砖都保持水平。
工匠二:先将一排砖都砌完,然后拉上一根水平线,看看哪些砖有问题,再进行调整。
你会选择哪种工作方法呢?你一定会骂工匠二笨吧!这样多浪费时间呀! 然而你自己想想,你平时在编写程序的时候又是怎么做的呢?我们就是按工匠二的方法在干活的呀!甚至有时候比工匠二还笨,是整面墙都砌完了,直接进行"集成测试",经常让整面的墙倒塌。看到这里,你还觉得自己的方法高明吗?
单元测试长期以来被忽视
每一个程序员都知道应该为自己的代码编写测试程序,但却很少这样做。当人们问为什么的时候,最常听到的回答就是:"我们的开发工作太紧张了"。但这样却导致了一个恶性循环,越是没空编写测试程序,代码的效率与质量越差,花在找Bug、解决Bug的时间也越来越多, 实际效率大大降低。由于效率降低了,因此时间更紧张,压力更大。你想想,为什么不拉上一根水平线呢?难道,我们不能够将后面浪费的时间花在单元测试上,使得我们的程序一开始就更加健壮,更加易于修改吗?抛弃原来的托词吧!
我们的自动化水平太低了
有人还会解释说,那是因为拉根水平线很简单,而写测试程序却是十分复杂的。我暂且对这句话本身不置可否。不过也体现了一个新问题,我们需要更加方便、省时的编写测试程序的方法。
要测试一个类,最简单的方法是直接在调试器中使用表达式观察对象的值与状态,你也可以在程序中加上一些断言、打印中间值等,当然还可以编写专门的测试程序。但是这些方法都有一个很大的局限性,都需要加入人工的判断和分析。
由此,自动化测试的引入才是解决之道。正是因为如此,提倡"测试驱动开发"的人群,开发出一系列的自动化单元测试框架xUnit,现在已经有针对Java、Pyhton、C++、PHP等各种常用语言的测试框架。这足以搪塞住那些以"编写测试代码太麻烦"为理由的开发人员,让他们没有理由逃避单元测试。
正如Robert Martin所说:"测试套件运行起来越简单,就会越频繁地运行它们。测试运行越多,就会越快地发现和那些测试的任何背离。如果能够一天多次地运行所有的测试,那么系统的失效时间就决不会超过几分钟"。
认清测试驱动开发
测试驱动开发理论最初源于对这些问题的思考:
1)如果我们能够在编写程序代码之前先进行测试方案的设计,会怎样?
2)如果我们保证除非没有这个功能将导致测试失败,否则就不在程序中实现该功能,会怎样?
3)换一个角度,如果当测试时发现必须增加某项功能才能够通过测试时, 我们就增加这一功能,会怎样?
大师们通过带着这些问题的实践, 发现这的确是一个提高软件代码质量, 使得效率得到保障的一个很好出发点。
以这样的思路进行软件开发,可以保证程序中的每一项功能都有测试来验证它是正确的,而且每当功能被无意修改时, 测试程序会发现。同时,也使我们获得了一个新的观察点,从对程序调用者有利的视角来观察我们的程序,这使得我们在关心程序功能的本身还能够对接口予以足够感悟测试驱动开发的关注,使得其更容易被调用。另外,这种思路下的代码,将变得更加易于调用,也就必须使其与其它代码保持低耦合性。并且,当你想复用这些模块时,测试代码给出了很好的示例。这一切,使得软件开发工作的质量一下子变得有保障了。
因此,测试驱动开发的精髓在于: 将测试方案设计工作提前,在编写代码之前先做这一项工作; 从测试的角度来验证设计,推导设计; 同时将测试方案当作行为的准绳,有效地利用其检验代码编写的每一步,实时验证其正确性,实现软件开发过程的"小步快走"。
实践测试驱动开发
下面,我就结合一个实际的小例子,来说明如何进行"测试驱动开发"。本实例在J2SE SDK 1.4.2环境下开发,以及配套工具JUnit 3.8.1。
任务简述
队列是一种在程序开发中十分常用的数据结构,在此我就以编写一个实现队列功能的类–Queue为例进行说明。该类将实现以下基本运算:
判断队列是否为空:empty()
插入队列(即在队列未尾增加一个数据元素):inqueue(x)
出队列(也就是将队列首数据元素删除):outqueue()
取列头(也就是读者队列首数据元素的值):gethead()
清空队列(也就是将队列的所有数据元素全删除): clear()
查询x在队列中的位置:search(x)
测试案例分析
在测试驱动开发实践中,第一步就是考虑测试方案,通过分析该类的功能,我们可以得到以下测试案例:
1) 队列为空测试
TC01: 队列新建时,应为空;
TC02: 清空队列后,应为空;
TC03: 当出队列操作次数与插入队列操作次数一样时,应为空;
2) 插入队列测试:
TC04: 插入队列操作后,新数据元素将插入在队列的未尾;
TC05: 插入队列操作后,队列将一定不为空;
3) 出队列测试
TC06: 出队列操作后,第一个数据元素将被从队列中删除;
4) 取队头测试
TC07: 取队头操作将获得队列中的第一个数据元素。
5) 清空队列测试
TC08: 清空队列操作后,队列将为空队列;
注: 此处为了讲解的方便,并未将所有的测试用例都列出,同时也选择了一些十分简单的测试用例。
第一次迭代
我们首先编写第一个测试代码,这一测试代码只考虑了测试案例TC01, 也就是保证新建的队列为空:
import junit.framework.*;
//每个使用JUnit编写的测试代码都应该包括本行
public class testQueue extends TestCase
//创建一个测试用例,继承TestCase
{
protected Queue q1;
public static void main (String[] args)
{
jun
it.textui.TestRunner.run (suite());
//执行测试用例
}
protected void setUp() //环境变量准备
{
q1= new Queue();
}
public static Test suite() //通用格式,指定测试内容
{
return new TestSuite(testQueue.class);
}
public void testEmpty() //以下每个方法就是一个测试
{
assertTrue(q1.empty());
//当队列新建时,应为空-TC01
}
}
安装JUnit十分简单,只需在www.junit.org中下载最新的软件包(ZIP格式), 然后将其解压缩,并且将"JUnit安装目录\junit.jar" 以及"JUnit安装目录"都加到系统环境变量CLASSPATH中去即可。
执行套件可以像上述程序一样在main方法中使用,也可以直接在命令行调用:java junit.textui.TestRunner 测试类名(文本格式)、java junit.awtui.TestRunner 测试类名(图形格式,AWT版)、java junit.swingui.TestRunner测试类名(图形版,Swing版)。
编译执行(即在命令行执行javac testQueue.java和javatestQueue), 你会发现屏幕上出现提示:
.E 一个小点说明执行了一个测试用例,E表示其失败
Time: 0.11 说明执行测试共花费了0.11秒
There was 1 error: 说明存在一个错误
1) testEmpty(testQueue)java.lang.NoClassDefFoundError: Queue
at testQueue.setUp(testQueue.java:13)
at testQueue.main(testQueue.java:9)
FAILURES!!!
Tests run: 1, Failures: 0, Errors: 1
测试没有通过是肯定的,因为Queue类都还没有写呢?怎么可能通过测试,因此,我们就编写以下代码,以使测试通过:
public class Queue extends java.util.Vector
{
public Queue()
{
super();
}
public boolean empty()
{
return super.isEmpty();
}
}
将这个类编译后,再次执行测试程序,这时将出以下提示:
. 一个小点说明执行了一个测试用例,没有E表示其成功
Time: 0.11
OK (1 test)
你还可以使用前面我们说到的另两个命令,使测试反馈以图形化的形式体现出来,例如,执行java junit.awtui.TestRunner testQueue, 将出现:
图1
第二次迭代
接下来,我们修改测试程序,加入测试案例TC04、TC05的考虑。
import junit.framework.*;
public class testQueue extends TestCase
{
protected Queue q1,q2;
public static void main (String[] args)
{
junit.textui.TestRunner.run (suite());
}
protected void setUp() {
q1= new Queue();
q2= new Queue();
q2.inqueue("first"); /对队列q2执行插入队列操作
q2.inqueue("second");
}
public static Test suite()
{
return new TestSuite(testQueue.class);
}
public void testEmpty()
{
assertTrue(q1.empty());
//当队列新建时,应为空-TC01
}
public void testInqueue()
{
assertTrue(!(q2.empty()));
//执行了插入队列操作,队列就应不为空-TC05
assertEquals(1,q2.search("second"));
//search方法用于确定元素在队列中的位置
//后插入的数据元素,应在未尾-TC04
//插入两个,第一个在位置0, 第二在位置1
}
}
根据这个测试代码,我们需要在Queue类中添加上inqueue() 和search() 两个方法,如下所示:
public class Queue extends java.util.Vector
{
public Queue()
{
super();
}
public boolean empty()
{
return super.isEmpty();
}
public synchronized void inqueue (Object x)
{
super.addElement(x);
}
public int search(Object x)
{
return super.indexOf(x);
}
}
编译之后,再次执行java junit.awtui.TestRunnertestQueue, 你将再次看到成功的绿色。
图2
我们仔细看一下这一界面。
1) 最上面列出了测试代码的类名,右边有一个"Run" 按钮,当你需要再次运行这一测试代码时,只需单击这个按钮。另外,将"Reload classesevery run" 选项打上勾很有用,当你测试未通过(出现红色时), 你可以转身去修改代码,修改完后,只需再按"Run" 按钮就可以再次运行。
2) 中间区域是一个状态汇报区,红色表示未通过,统计了共运行了多少个测试(也就是在TestCase类中方法的数量)。
3) 如果测试时出现错误,例如,我们不小心将"assertTrue(!(q2.empty()));" 误写成为"assertTrue(q2.empty());" 就将造成测试失败:
注:由于第一个测试还是通过的,因此你会看到绿色条一闪。这时,你将会发现JUnit会将错误列出来,并且对应的"Run"按钮也由灰变成了亮,这表示你可以转身修改,完成后单击这个"Run按钮"可以只做刚才失效的这个测试,这将节省大量的时间。
同时,在最下面的窗体里,列出了失效的详细原因。
后面的迭代
到这里,开发还没有完成,但这种思想却已经通过这样两个短小的实践传递出去了,后面的活大家可以动手试一下。
另外值得一提的是,这里虽然洋洋洒洒一大篇,实际两次迭代花费了我不到15分钟就完成了。而且,当看到绿条时,心里十分舒畅。
一些遗憾
文章到此就告一段落,但却有些许遗憾。
遗憾之一:这只是一篇文章,没有办法把所有方面都讲得面面俱到,以致于大家可能无法马上上手。
正是由于这样的原因,本文取名为"感悟", 与大家交流一下体会,希望能够帮助大家更好地接受"测试驱动开发"的理念,并开始着手实践。
遗憾之二:笔者水平有限,无法解决大家的各种问题。
让笔者感到欣慰的是,记载着这些答案的《测试驱动开发》、《敏捷软件开发》、《拥抱变化: 解析极限编程》等大作都已悉数摆上了中国的书店。路虽难走,但明师已有。
实践永远是学习的最好方法,看到笔者的感悟,就开始极限之旅吧,因为那里风光无限,乐趣无限。当你掌握了测试驱动开发的精髓,那你就能够对你自己编写的所有代码充满信心,不再担心它们什么时候在你的后面放一冷箭,从此告别这给你带来无限压力的苦恼。
Visual C# 3.0 新特性概览
Filed Under (默认分类) by 刘 鹏 on 23-08-2006
在发布Visual Studio 2005和C#2.0之后,微软公司又马不停蹄的展示了人们所期望的C#的下一代版本:C# 3.0。尽管C# 3.0并没有标准化,微软还是在PDC(专业程序员会议)发布了一个预览版本,因此心急的程序员可以看到一些所期望的特性,这也是本文所讨论的主要内容:
·隐式类型本地变量
·匿名变量
·扩展方法
·对象和Collection初始化符
·Lambda表达式
·查询表达式
·表达式树
隐式类型本地变量
C# 3.0引进了一个新的关键字叫做"Var"。Var允许你声明一个新变量,它的类型是从用来初始化符变量的表达式里隐式的推断出来的。也就是说,如下的表达式是有效的格式:var i = 1;
这一行使用了1来初始化符变量i。注意这里i被强类型到整型,它不是一个对象或者VB6的变量,也不带有其他对象或者变量的负载。
为了保证使用var关键字进行声明的变量的强类型特性,C#3.0要求你将赋值(初始化符)放到和声明(声明符)的同一行。同样,初始化符必须是一个表达式,不能是一个对象或者collection初始化符,也不能为null。如果多个声明符对同一个变量存在,那么它们必须在编译时被视作相同类型。
另一方面,隐式类型数组,可以使用一点不同的格式,如下所示:var intArr = new[] {1,2,3,4} ;
上面一行的代码将声明intArr为int[].
var关键字允许你使用匿名类型的实例,因而这些实例就是静态类型的。所以,当你创建一个包含一组数据的对象的实例的时候,你不必要预先定义一个类可以同时支持这个结构和在一个静态类型变量里的数据。
匿名变量
C# 3.0使得你可以灵活的创建一个类的实例,而无需先写这个类的代码。所以你可以这样写代码:new {hair="black", skin="green", teethCount=64}
上一行代码,通过new关键字的帮助,创建了有三个属性的类型:hair,skin和teethCount。这样C#编译器就会创建一个类如下:class __Anonymous1
{
private string _hair = "black";
private string _skin = "green";
private int _teeth = 64;
public string hair {get { return _hair; } set { _hair = value; }}
public string skin {get { return _skin; } set { _skin = value; }}
public int teeth {get { return _teeth; } set { _teeth = value; }}
}
事实上,如果另外一个满足了相同的名称和类型顺序的匿名类型也被创建了,编译器也会聪明的只创建一个匿名类型来支持两个实例来使用。同样,因为实例都是一个类的简单实例,它们可以进行互换因为类型实际上是一样的。
现在你拥有了这个类,但是你还需要一些东西来支持以上的类的某个实例。这就是"var"关键字的作用。它让你拥有一个以上匿名变量的实例的一个静态类型实例。这里有一个简单好用的匿名类型的使用例子:var frankenstein = new {hair="black", skin="green", teethCount=64}
扩展方法
扩展方法使你能够使用额外的静态方法来扩展各种类型。不过它们是非常有限的,也只能在实例方法不足够的情况下才作为候补使用。
扩展方法只能在静态类中被声明,并且以关键字"this"放在方法的第一个参数前来标识,如下就是一个有效的扩展方法的例子:public static int ToInt32(this string s)
{
return Convert.ToInt32(s) ;
}
如果一个包含以上方法的静态类被使用"using"关键字引进,ToInt32犯法将会出现在已有的类型中(虽然比现有的实例方法优先级低),你可以这样编译和执行代码:string s = "1";
int i = s.ToInt32();
这使得你可以充分享用各种以有的内建的或者定义的类型的扩展特性,并且给它们加上新的方法。
C# 3.0被希望来允许你包含一个初始化符,从而指定一个新创建的对象或者collection的初始值。这使得你能够一步结合声明和初始化。
举例来说,你可以这样定义CoOrdinate类:public class CoOrdinate
{
public int x ;
public int y;
}
你然后可以使用一个对象初始化符来声明和初始化一个CoOrdinate对象,就像这样:var myCoOrd = new CoOrdinate{ x = 0, y= 0} ;
也许你要问,为什么不要像下面这样做呢?var myCoOrd = new CoOrdinate(0, 0) ;
注意:我从来没有为我的类声明过一个接受两个参数的构造器。事实上,使用一个对象初始化符来初始化对象等同于调用一个无参数(缺省)构造器并且给相关量赋值。
类似的,在C#3.0里你可以轻松的用一种更加简洁的方式给collection赋值,如下的C# 2.0的代码:List
animals.Add("monkey");
animals.Add("donkey");
animals.Add("cow");
animals.Add("dog");
animals.Add("cat");
可以缩短为:List
Lambda表达式:匿名方法的浓咖啡
C# 1.X允许你在方法里写代码段,你可以轻松的使用委托(delegate)来调用。委托无疑是有用的,并且可以在框架里任意使用,但是在很多实例里你必须为了使用它而声明一个方法或者一个类。因此,为了给你一个更加容易和简洁的编码方式,C# 2.0允许你使用匿名方法替换标准调用到委托。如下代码可以在.NET1.1或者更早的版本看到:class Program
{
delegate void DemoDelegate();
static void Main(string[] args)
{
DemoDelegate myDelegate = new DemoDelegate(SayHi);
myDelegate();
}
void SayHi()
{
Console.Writeline("Hiya!!") ;
}
}
在C# 2.0,使用匿名方法,你必须这样重写代码:class Program
{
delegate void DemoDelegate();
static void Main(string[] args)
{
DemoDelegate myDelegate = del
egate()
{
Console.Writeline("Hiya!!");
};
myDelegate();
}
}
尽管匿名方法对基于方法的委托调用更进了一步,但是Lambda表达式允许你用更加简洁,功能性的格式写匿名方法。
你可以将Lambda表达式作为一个参数列表来编写代码,跟在=>后面,再跟上一个表达式或者语句。以上的代码可以用如下的代码替换:class Program
{
delegate void DemoDelegate();
static void Main(string[] args)
{
DemoDelegate myDelegate = () =>Console.WriteLine("Hiya!!") ;
myDelegate();
}
}
尽管Lambda表达式显得更加简洁,实际上他们也是一个匿名方法的功能性超集。特别的,Lambda表达式提供了如下的额外的功能:
·它们允许参数类型是被推断的。匿名方法要求你必须清楚的陈述每个类型的状态。
·它们可以支持查询表达式或C#语句。
·它们可以被看作使用表达式树的数据。这是不能用匿名方法来做的。
查询表达式
这个特性使得你可以在C#中使用SQL类似风格的语句,也被称作LINQ(语言集成查询)。
举例来说,你可以这样描述你的数据:ublic class CoOrdinate
{
public int x ;
public int y;
}
在C#里,你可以像下面一样轻松的声明一个数据库表的逻辑等同式:// Use Object and collection initializers
List
现在你的数据可以作为一个collection来实现 IEnumerablevar filteredCoords =
from c in coords
where x == 1
select (c.x, c.y)
在以上SQL风格的格式中,"from"、"where"和"select"是查询表达式,用到了C# 3.0的一些特性如匿名类型,扩展方法,隐式类型本地变量等。这样,你可以使用SQL风格的格式,将无联系的数据整合一起来工作。
每个查询表达式实际上转变为一个C#的调用,如:where x == 1
将会转换为:coords.where(c =>c.x == 1)
你可以看到,这个看上去很像一个可怕的Lambda表达式和扩展方法。C# 3.0还有其他很多关于它们的查询表达式和规则。
表达式树
C# 3.0包含了一个新类型,允许表达式能够当作运行时的数据使用。这个类型,System.Expressions.Expression
如下是一个表达式树的例子:Expression
使用如上的表达式树的方法,你可以使用过滤器变量中的各种属性来检查树的内容。
结束语
C# 3.0提供了一些新的特性,使得你可以更轻松的完成一个程序员和架构设计师的工作,同时也保持了程序语言的严谨和清晰的结构。
C# 3.0目前还处于襁褓中,还将在未来的数月中长大,但是它所能改变的一切,紧靠其强大的后盾.NET框架,它的体系结构和设计模式,值得你的关注。
ISCS2006合影
Filed Under (默认分类) by 刘 鹏 on 22-08-2006
序言
今年是正式步入IT界的第二年,一直想着能对过去的经历做些回顾与反思,以更好地走向未来,但总苦于没有心思,今天发觉BLOG的内容太少,于是就将过去写的这片文章改了下下.
在此,记录下我的生活足迹,由于长期编程,记忆力有所减退,有些事记得不太清了,但我是尽量真实的记录当时的情况,有兴趣看我这篇文字的人请把我看成是一个在生活在你的轨道中间一起喜怒哀乐,一起努力的平凡人,相信我们之间会有很多跨越时空的情感交流。
2002-2006不知不觉在IT技术世界里已经侵泡了3年。在我10岁的时候我父母就离婚了,他们都是个体户,家境仅能解决温饱,我想我可能代表中国社会一大类青年,我的经历与体会可能会对许多条件并不好的新手有所启示:只要努力,天资差与环境不好都是可以克服的。首先说我不是牛人,我只是尽量真实地写下我的经历与感触,写一个平凡人的努力过程。
一、失败的学业
2000年,是很颓废的一年,心高气傲的自己居然只能进入一所三流中学读书。记忆中的那一年,是很阴沉的。年少轻狂的自己用很消极的态度对待自己的学业,麻木地去拼搏那所谓的未来,计算机对我来说也只是一门课程而已。那个时候,学校安排上机都是用UCDOS上WPS练习打字,那个时候还得背五笔字根“王旁青头…”。
也许我天生就无法接受中国应试教育,初一读完初二就退学了。父亲在当地为我联系了一家做硬件公司在那做学徒。与其说是在那里学习,倒不如说当免费的勤杂工,每天早上8点就去开门,打扫卫生。由于我老家在山区,那里做IT生意很差,所以学习机会很少,只有看师傅在那里玩游戏,偶尔有机会接触到机器,那也是拆机器。还记得那年冬天,因为天气干燥经常被静电电的汗毛都竖起来了~~~~~。到2003年《传奇》在国内很火暴,不幸我迷恋上了这款游戏,至于迷恋到何种程度我就不说了,因为这段时间在我记忆中是很阴暗,很堕落不想再提起了……。
二、艰辛学习路
2003年8月,母亲不让我再这样堕落下去,把我送到四川长城职业培训学院上学。这所学校里面的学生有两种:一种是在学校整天无所事事混时间的,等到毕业的时候后学校推荐个工作到沿海城市去当工人(去了女生当男生用,男生当畜生用)。还有一种,就像我这样被骗来的。当初报名我还选择我的老本行,刚进校时一心想在学校多学点技术。可惜这里学生大多来自农村,以前接触过计算机的现在仍然要从最基本的开始,第一学期只有两门和计算机相关的课程:Windows98和汉字录入,其他的还有电子课,数学,语文。当时的又想退学。2003年11月,我母亲为了能让我安心在这里上学,于是把自己省吃俭用下来的积蓄拿出来给我买了台电脑。从此我有了属于我自己的电脑,10多年以来的愿望终于实现了。有了电脑以后,每天下午5:30放学我就狂奔回家,然后开电源,接着洗脸洗脚,之后就开始学习,吃饭的时候把显示器关了,用最快的速度把不知道为何味的饭塞进肚子,然后又开始漫长的学习,12点后的躺在床上看书学习理论知识。
当初我选择的C语言,听别人说学好了它将来学其他语言都很容易上手,说到这里我得提起一个人我母亲的一个朋友–张阿姨,那时候得知我要学习C语言,送我了两本书:《C语言程序设计》和《数据结构》,到现在这两本书我一直保存着,即便现在一人独自在异乡也随身带着。两本书是不值什么钱,重要的是这份心意,它也许会成为我人生中的一笔财富。在我众多亲戚里没有人支持过我,认为我学计算机就为了打游戏,都认为我将来是个混混。那时候学校还没有开设C语言的课程,全是自学,我自学了2个月,把编程的基础基本掌握了,就没学了,后来看见我一个朋友做一个学校网站,我很感兴趣,于是开始学习网页制作,最早是用FrontPage做静态网页,学了一段时间后勉强能做些简单的页面,页面都是乱七八糟的,连用表格排版都不会。有次看见别的网页源代码里没有文字内容全是包含在SCRIPT标签,但浏览的时候又可以看见。就这一问题我郁闷了几周,后来才知道他是用script标签调用ASP生成的javascript文件,经过一短时间的折腾总算掌握了HTML。然后就开始用DreamWeaver学做ASP动态网页(VBSCRIPT)。那时候学校里没老师会ASP!只有靠自己自学,自学又没有书,当地书店里也没卖,家里也没有网络。我只有硬着头皮看别人的源代码,我看的第一个ASP源代码是一个叫AYSOFT的ASP+ACCESS留言板,非常简单的一个留言板,后来一点一点的琢磨,慢慢的对ASP的对象和组件以及Vbscript的语法有所了解。
2004年湖南卫视举办的超级女声风靡全国,我本人是不喜欢看那些的,电视都很少看,一次偶然在电视上看见张含韵,一见如故并且成了她的铁杆粉丝,我竭尽全力用我浅薄的技术打造出她的个人网站《寻找张含韵》那时候很穷,租不起服务器,只好拖朋友找“肉鸡”,那段时间网站人气还蛮旺,正因为这样我找到了学习的乐趣,水平得到了进一步提升,后来还做了《超级女声站》(现在已退出)等网站。可以这么说,超级女声改变了某些女孩的命运,同时也改变了我“命运的方向”。
二、曲折实践路
转眼就到了2005年了,我们03级中专班就要毕业了,那段时间很多工厂都来学校招聘工人,很多同学都在愁工作的事,都想进个福利好、待遇好的工厂。开始我觉得应聘很好玩,就去试一下。我应聘的那个厂是台资企业,是世界上最大笔记本电脑生产厂商-广达上海制造城,也是学校推荐工作最好的厂,这次还是我有生以来第一次应聘,开始有点紧张,以为会出一些很难的问题,结果问我“计算机有那些硬件?ACCESS是什么,C语言是什么”诸如这样的白痴级问题….就这样我不幸被聘上了,本来我并不打算去,可母亲非要我去!母命难违啊…….没办法去就去呗…出去见见世面也好。4月10日左右吧,我也记不清楚了,我和我同学们登上了开往上海的火车,坐了30多个小时的火车我们到了上海,后来坐厂里的大巴去厂里报道,第二天就开始安排工作,其他外省学校的人有分到生产MAC的,有生产DELL的。不幸的是:我们学校的“精英”被分到广达的子公司达辉电子生产液晶显示器,在这里面工作可就痛苦了,要穿无尘服在无尘车间工作,感觉就象是在抗“非典”,一进去就感觉呼吸困难,头晕目眩,那些台湾人根本都没把大陆的员工当人看,动不动就是一顿暴骂,我进去的第一天,看见一个湖南的同仁,就因为说错了一句话,被一个台湾恶女人骂了一天,那位同仁受不了第二天就辞职了。后来听老员工说类似这样的事经常发生的要我自己小心点就是了。在这里我做了10多天就辞职了,我在里面的工作就搬箱子,一天要搬几百箱,我整天都是提心吊胆的,真怕自己哪里没做好,会被一顿暴骂,这里根本没有我的发展空间,这是我第一次进台企,也是最后一次。辞职后很郁闷,天天泡网吧在上海的求职网站
2006中国共享软件国际论坛
Filed Under (默认分类) by 刘 鹏 on 11-08-2006
会场
今天是2006年中国共享软件国际论坛开幕,有幸今天我代表公司和老大还有同事参加了这次的盛会,早上8点起床,急急忙忙乘车去四环的世纪金源大酒店。
到了会场的门口看到很多人,有软件作者、有主办方CNSW(中国共享软件联盟)的成员、Digital River的主要领导,还有很多媒体记者等等。十点钟会议正式开始,第一个上台讲话的是Digital River的副总裁Brant Pallazza,为大家讲解国际共享软件发展趋势,展示了一些国外共享软件和国内共享软件以及国内出口软件的收入统计数据,其次是CSDN总裁蒋涛为大家讲解了共享软件未来的发展,然后就到午餐时间。下午2点去听了Digital River的技术总监Mike Halls讲解破解软件对行业的影响,这次论坛上最有趣的话题是Mike Halls问了一句“为什么这么多破解都来自中国?”,嘉宾A回答:“据我的了解,有很多的破解都来自俄罗斯,俄罗斯黑客的技术水平其实是非常高的,其实有众多的破解来自中国我不太赞同这个提法,因为在全球各地水平非常高的破解程序员都存在,可能中国的人口数量里面,程序员的数量相对比较多一些。”嘉宾B提问:“今天下午的报告里面也说到了,为什么破解到了美国之后,没有这个办法?”Mike Halls:“这是因为美国的法律都是特定的,这样的话,有一些破解网站可以用一些方法绕过这个规定,比如美国法律有这样一个规定,就是不能在你的网站上对别的正常网站的破解这个补丁,不能放在网站上,但是没有说禁止在这个网站上摆一个链接,然后这个链接是境外的网站上,这个是不违反美国法律的。另外一点,注册码的问题就是说我们在美国有言论自由,所以假如把注册码公布出来,在法律上是受保护的,不能禁止。”到3点此次论坛结束后我刚走出会议室门口,接待人员告诉我discuz的《社区与共享软件的发展》在另一个会议室举行,随后在接待人员的带领下去了分会场,此论坛是discuz的总裁/创始人:戴志康主持的,会场没几个人,只听他一个人在那里神侃,我呆了几分就闪人了。到下午4点半,我和同事又去了另一个会场《中国共享软件现状与流氓软件》,这是今天最没有意义的论坛,如果用BBS的行话说就是灌水,就几个嘉宾宣传自己的企业。
今天参加此次论坛的大牛不是很多,很多著名的软件作者都没来,有的作者都还来不及交换名片,今天的收获还算不错,认识了些业内著名人士,这对将来我在行业内发展都有好处,现在感觉我选择的行业真好,比娱乐圈还好玩。
19870202.com开通啦
Filed Under (默认分类) by 刘 鹏 on 02-08-2006
由于近期,工作特别忙..再加上最近自己在开发一个浏览器..暂时个人网站的项目延后..暂时找了一个AJAX+ASP.NET的BLOG系统放上来.呵呵.感觉这系统还不错…
关注我.关注wwww.19870202.com


