体验Microsoft.NET–与初学者一起用.NET写猜数字游戏

体验.NET

微软公司正在领导一次新的互联网技术革命,这就是.NET。.NET是一种全新的基于Internet的编程模型。2月13日微软公司在美国正式发布了全新的基于.NET平台的开发工具——Visual Studio.NET,这标志着微软.NET时代的全面到来。

我想通过本文,和大家一起用.NET开发一个简单的小游戏——猜数字,与大家一起分享我在学习.NET技术中的一些心得体会,分享.NET带给我们的全新的开发体验。

体验Microsoft .NET之基础篇

作为一个全新的开发平台,在Visual Studio.NET发布之前,微软公司已经正式发布了.NET Framework的SDK,这是我们进行.NET开发的基本条件。这个曾经被称为是NGWS(Next Generation Windows Services)的SDK提供给了我们包括C#(读音为C Sharp)编译器、VB编译器、ASP.NET运行环境等一系列.NET支持平台和相关的文档。

SDK只是一个简单的开发平台,如果你安装了.NET Framework SDK,你就可以开发一系列的.NET应用,但是你将无法充分体验到.NET带给我们的快速开发的乐趣,你仍需要使用古老的MSDOS命令行的方式来编译你的程序。因此,我们还需要安装Visual Studio.NET集成开发环境,有了它我们才可以真正体验到.NET开发的乐趣。Visual Studio.NET中文正式版已于3月22日正式发布。由于条件所限,本文中使用的Visual Studio.NET为英文正式版,但所涉及到的程序均可以在中文正式版中编译运行。

Microsoft Visual Studio.NET是专门开发基于.NET平台应用的集成开发环境,包括Visual Basic.NET、Visual C++.NET和最新的Visual C#.NET等一系列的开发工具,通过这个强大的开发环境,我们可以轻松构造包括Windows Forms应用程序、ASP.NET或是XML Web Service在内的各种.NET应用。

说了这么多,你该明白该怎么做了吧,打开您的计算机,安装.NET Framework SDK和Visual Studio.NET,然后就和我一起开始我们的.NET之旅吧!

体验Microsoft .NET之C#程序语言

C#语言是.NET平台中一个很重要的组成部分,它是由微软公司领导研究开发的新一代面向组件的编程语言,它既保持了C++语言所具有的强大的功能,又在此基础上提供了更多简单、安全的编程手段。.NET平台自身的很大一部分就是用这种新型的C#语言来开发的。

依照惯例,我们还是从“Hello World!”开始,体验一下C#语言。下面就是一个典型的C# HelloWorld程序:

using System;
public class Hello
{
public static void Main()
{
Console.WriteLine(“Hello world!”);
}
}

怎么样?不难吧。有点像C,有点像C++,有点像Visual Basic,更像JAVA。

程序的第一行指定了一个对于System名字空间(Namespace)的引用,引用了这个名字空间,我们下面才能方便的使用这个名字空间中的类,例如下面的Console类就是属于System这个名字空间的。第二行开始我们定义了一个Hello类,它包含一个静态的Main方法(Method),C#中没有了成员函数的概念,原来的成员函数现在称为是“方法”,而原来的成员变量被称作“字段(Field)”。Main方法是一个C#程序的开始。在我们的例子中,Main方法唯一的一行可执行代码调用了系统Console类的输出方法显示字符串“Hello world!”。

下面我把C#与C++进行一个简单的对比:首先,C#是完全面向对象的程序设计语言,它不再有全局的函数,任何函数都被包含在某个类中成为方法。C#中不再需要函数的前向声明,你所需要的函数可以定义在类中的任何位置。C#在最大程度上避免了指针的使用,同时,原来C++中的::、->和.操作符被统一为了.。C#不再使用#include来包含其它的程序文本,这使得.NET平台的语言无关性得以体现。举个例子,你可以使用Viusal Basic.NET写一个类,然后用C#去调用它甚至在它基础上派生新的类,这使得软件复用达到了一个新的境界。

下面你就可以试一试了,这里,我们暂时不使用Visual Studio.NET,我们用命令行的方式来编译运行这个程序。

打开记事本,输入上面的源代码,注意大小写,然后存盘,把文件扩展名改成.cs(这里我们把这个文件存为hello.cs),这是C#源程序要求的扩展名。然后打开一个DOS窗口,找到你存放.cs文件的目录,输入

csc hello.cs

系统就开始编译你的程序,如果没有出错的话,会生成hello.exe文件,运行这个文件,就可以看到屏幕上的输出了。

下面我们来使用Visual Studio.NET来进行C#程序的开发。

首先肯定是要启动Visual Studio.NET软件。下面就是它的开发界面,很漂亮也很友好。

Visual Studio .NET主界面

Visual Studio .NET主界面

我们点击起始页面上的“New Project”按钮新建项目,在弹出的“New Project”对话框中选择项目类型为“Visual C# Project”,并选取“Console Application”(控制台应用程序)模板,输入合适的项目名称(我们这里用GuessNum1)和存放位置,确定。这时系统会为我们生成一个最简单的C#应用程序的框架,我们可以在其基础上修改成我们自己的程序。

新建项目

新建项目

我们把系统生成的程序框架修改成下面的样子:

using System; //引用系统System名字空间

namespace GuessNum1 //定义属于本程序的名字空间
{
///<summary>
/// Summary description for Class1.
///</summary>
class Class1 //系统自动生成的Class1
{
///<summary>
/// The main entry point for the application.
///</summary>
[STAThread]
static void Main(string[] args) //静态Main方法
{
//
// TODO: Add code to start application here
//
GuessNum gn = new GuessNum(); //GuessNum 类生成一个对象
gn.GenerateRandomNumber(); //产生随机数作为被猜的数字
string answer; //字符串变量,用于保存用户输入的猜测值
do
{
answer = Console.ReadLine();
Console.WriteLine(gn.GetTip(answer));
} while(!gn.IsAnswerRight(answer)); //反复要求用户猜数直到猜测正确
}
}
class GuessNum //我们自己定义的GuessNum类,以后还要多次用到
{
private string correctAnswer; //GuessNum类的私有字段(成员变量),用于保存正确答案
public GuessNum()
{
correctAnswer = “”;
}
public GuessNum(string answer)
{
correctAnswer = answer;
}
public string GenerateRandomNumber()
{
int [] a = new int [10]; //开辟一个十个单元的整形数组
//09十个数字依次填入a[0]a[9]
for(int i = 0; i < 10; i++)
a[i]=i;
//把这个十数字随机打乱
Random j = new Random();
for(int i = 0; i < 10; i++)
{
int t = j.Next(10);
int s;
s = a[i];
a[i] = a[t];
a[t] = s;
}
//取前四个数字组成四位数做为猜数字的正确答案
correctAnswer = a[0].ToString() + a[1].ToString() + a[2].ToString() + a[3].ToString();
return correctAnswer;
}
public string GetTip(string answer) //本方法为用户提供猜测提示,目前还没有真正完工
{
if (IsAnswerRight(answer))
return “4A0B”;
else
return “Wrong!”;
}
public bool IsAnswerRight(string answer) //本方法判断用户的猜测是否正确
{
if (answer == correctAnswer)
return true;
else
return false;
}
}
}
相信在代码输入的过程中你一定会体验到Visual Studio.NET强大的代码编辑功能,自动缩进对齐、智能感应、代码折叠应有尽有。

上面的程序本身没有什么太多的可以解释的地方,可以看到,这个程序随机产生了一个四位数字各不相同的四位数,然后等待用户输入,如果输入正确,就显示“4A0B”(这个不用我再详细解释了吧,玩过猜数字的朋友都知道这个提示的含义,A前面的数字表示你猜对了并放对位置的数字个数,B前面的数字表示你猜对了数字但放错了位置的数字的个数),如果猜错了,就显示“Wrong!”,让用户重新猜测。很明显这个游戏现在还不好玩,猜错了仅仅提示“Wrong!”是远远不够的,应该告诉用户猜对了几个数字和放错位了几个数字才行。不要着急,我们会在后面慢慢完善这个程序。

这个程序中有一个值得注意的地方是它使用了“///”形式的注释,这样的注释可以用来自动产生程序文档,如果在里面加上一些标记还可以产生XML形式的文档。

现在你就可以按下Ctrl+F5键运行程序了,输入一个4位数,如果正确,系统为提示“4A0B”并退出程序,如果不正确就输出“Wrong”。由于没有足够的提示,恐怕你是不太可能猜到正确的数字的,所以还是把窗口关了,我们继续下面的内容。

体验Microsoft .NET之Windows Forms程序设计

前面我们已经在控制台环境下进行了一点C#程序的开发,目的只是让大家熟悉一下C#语言,下面我们将把我们在控制台下开发的程序移植到Windows窗口界面中。

这里,我们首先引入Windows Forms的概念:Windows Forms是微软在.NET平台下提供的一种程序构架(Framework),它可以支持多种程序语言,主要用于开发客户端的窗口应用程序。

下面我们就用Visual Studio.NET帮我们生成一个简单的Windows Forms源程序,我们将在它的基础上工作,方法如下:

打开Visual Studio.NET,点击“New Project”,选择项目类型为“Visual C# Project”,然后选择程序模板为“Windows Application”,输入项目名称“GuessNum2”,确定。

我们按F5键编译运行这个程序,一个空白的窗口就出现了。我们现在要做的就是给这个空白窗口加上我们需要的功能。

首先,我们进行可视化的界面部分的构造,从左边的Toolbox中找到合适的控件,拖曳到空白窗口上,使它成为下面的样子:

窗体设计器

窗体设计器

要说明的一点是,在构造TextBox2时,要注意把它的MultiLine属性和ReadOnly属性设为True。并把ScrollBars属性设为Vertical。控件属性值的修改是通过选中控件后用Visual Studio.NET集成环境右下角的“Properties”区域来实现的,修改过的属性,其属性值的字体会变粗。这个Properties区域还有一个功能就是可以为控件连接不同事件的响应函数,可以通过点击上面的Events按钮来切换功能。

属性设置

属性设置

双击窗体的空白部分,系统自动为你生成了这个窗体的Load事件响应函数Form1_Load(),我们先不着急修改它,先把在上一个程序中写的GuessNum类的代码(不包括Class1类的代码)贴在当前代码窗口中的代码的最后一个}前,使这个类成为当前的GuessNum2名字空间中的一个类。

然后在Form1类中写上下面的代码,即在Form1类中定义一个GuessNum类的对象gn。由于C#不要求前向声明,应此这行代码可以写在Form1类中的任何位置,当然不包括Form1类的方法中,如果你把这行代码写在Form1类的某个方法中,这就不是在类中定义对象而变成是在某个方法中定义的局部对象了。

private GuessNum gn;

然后我们再修改Form1_Load(),把它修改成下面的样子:

private void Form1_Load(object sender, System.EventArgs e)

{

textBox1.Text = “”;

button1.Text = “Guess!”;

//GuessNum类生成一个对象,然后让它产生被猜的数字,最后把这个数字显示在TextBox2

//之所以把它显示在TextBox2中是为了便于你偷看答案,否则凭空猜是几乎不可能猜到答案的

//我们会在后面的程序中完善GuessNum,使它的GetTip()方法可以真正起作用

gn = new GuessNum();

textBox2.Text = gn.GenerateRandomNumber();

}

点击代码编辑器上部的标签,切换回窗口设计器,双击button1按钮,为它添加按钮响应函数如下:

private void button1_Click(object sender, System.EventArgs e)

{

textBox2.Text = (textBox1.Text + ” ” + gn.GetTip(textBox1.Text) + “/r/n” ) + textBox2.Text;

if (gn.IsAnswerRight(textBox1.Text))

textBox2.Text = “Congratulations! You get it!/r/n” + textBox2.Text;

textBox1.Text=””;

}

我们再次使用F5编译运行这个程序,看,很方便的,我们就把刚才在控制台下运行的程序改成了Windows应用程序。

体验Microsoft .NET之ASP.NET

下面我们来看看.NET的重要组成部分ASP.NET的情况。我们将演示用ASP.NET迅速开发一个可以在Web上玩的猜数字游戏。

在Visual Stuido.NET中,我们新建一个ASP.NET应用程序,操作方法与上面的基本相同,只不过在选择项目模板时选择为“ASP.NET Web Application”,这次,我们用GuessNum3作为我们的项目名称,确定后系统会自动与IIS服务器联系,为你建立好虚拟目录和一些相关的文件。

同前面一样,我们按F5运行这个ASP.NET项目,同样的我们也是得到了一个空白的页面。

下面要做的工作与前面的类似,首先要在空白的ASP.NET页面上添加服务器控件。什么是服务器控件?简单的说,服务器控件就是在ASP.NET页面上放置的一种控件,这种控件的正常工作是在服务器端完成的,服务器在处理完控件动作后,再生成标准的HTML文件发送给客户端。比如:我们在页面上放置一个Label控件,并通过程序改变它上面的文字为“Hello World”,服务器在收到用户访问这个页面的请求时,它对Label控件进行控制,改变它的标题属性,最终生成HTML文件发送给用户,用户对于这幕后的一切并不知道,他最终收到的数据,就是一个包含着“Hello World”字符串的HTML页面。

在页面上添加服务器控件的方法与前面在窗体上添加控件的方法完全一致,只要从Toolbox中点中相应的控件,拖放到页面上就可以了。我们最终完成后的页面是这样的:

ASP.NET页面设计器

ASP.NET页面设计器

同样的,不要忘了把textBox2的ReadOnly属性设为True,把TextMode属性设为MultiLine,。另外为了后面的操作可以方便一些,请把这三个控件的(ID)属性的第一个字母改成小写,即把这三个控件的ID由原来的TextBox1、TextBox2、Button1改成textBox1、textBox2和button1。

接下来要做的工作也许会让你觉得有点似曾相识:

双击页面空白处,系统为你生成Page_Load()方法,不管它,在源程序的最后一个}前加入我们上一个程序中的GuessNum类,然后在WebForm1类中加入一行:

private GuessNum gn;

然后修改Page_Load()成下面的样子:

private void Page_Load(object sender, System.EventArgs e)

{

// Put user code to initialize the page here

//判断是第一次访问页面还是刷新过页面

//如果是第一次访问,产生随机数并存在Session

//如果不是第一次访问,从Session中读出前面产生的值用于构造GuessNum对象

if (!Page.IsPostBack)

{

textBox1.Text = “”;

button1.Text = “Guess!”;

gn = new GuessNum();

//下面用到了ASP中熟悉的对象Session,但是ASP.NET中的SessionASP中的更强大

Session[“answer”] = gn.GenerateRandomNumber();

//同上一个Windows Forms程序一样,我们把标准答案先显示在textBox2中,便于你测试程序

textBox2.Text = Session[“answer”].ToString();

}

else

gn = new GuessNum(Session[“answer”].ToString());

}

返回Web表单设计器,双击Button按钮,在出现的button1_Click()中加入与上一个Windows Forms程序中相同的代码。

好了,运行一下试试。不出所料,一个可以在Web上运行的猜数字游戏已经初具雏形了。

经过上面的演示,你是不是对ASP.NET有了一个初步的认识呢?在ASP.NET中,不用再像从前在ASP中那样把脚本插在HTML文件中,进行了界面设计与程序设计的分离(把页面设计的部分放在一个.aspx文件中,把代码部分放在一个.cs或.vb的代码文件中,该技术被称为Code Behind),并且使ASP.NET页面也呈现出一种事件驱动的特性。这就使得代码的重用性得到大大的加强,就像你看到的那样,我们在ASP.NET中使用的代码与在Windows Forms桌面应用程序开发中使用的代码是相当一致的。

另一方面,ASP.NET的代码分离技术不但提高了开发效率,也提高了运行效率,ASP.NET不再是解释执行的,它是在用户第一次访问一个新的页面时,对那个页面的代码进行编译,以后的用户访问就执行的是编译后的代码,运行效率自然有了巨大的提高。这也是为什么我们感觉的ASP.NET网页第一次访问时速度特别慢的原因。

从用户的角度来看,ASP.NET也更容易使用了,访问一个ASP.NET页面就像是使用一个应用程序一样。事实上,我们上面编写的Windows Forms的应用程序也不同于一般的应用程序,如果把它放在Web上,当用户点击指向它的链接时,浏览器会直接自动下载并运行它(当然,微软公司做了很多工作来保证其安全性)。在.NET时代,网络与桌面应用程序的界线已经越来越不明显。

体验Microsoft .NET之Web Service

Web Service是微软在.NET中引入的一个较新的概念。在传统的应用程序开发过程中,开发人员一直通过集成本地系统服务来构建应用程序。现在Web Service的出现,可以让开发人员轻松的构建具有复杂结构的N层系统。Web Serivce是这样的一种应用程序,它使用标准的HTTP协议和XML,将软件的功能体现在网络上。明确一点说,就是在Web服务器上开发一个应用程序,它可以响应远程程序的请求、接受运程程序发来的数据,处理后再将数据返回。

下面我们想通过Web Service为我们的猜数字游戏提供一个产生提示信息的的服务,也就是说,客户端应用程序将猜数字的标准答案与用户所猜的数字提供给服务器上的Web Service,服务器判断用户猜测的正确性,并返回猜对并放对位置的数字个数和猜对但未放对位置的数字个数。有些朋友一定会问,这个操作明明可以在本地完成,为什么要转个大圈子,在服务器上用Web Service完成呢?这个操作确实可以直接在上面的C#程序中添加代码完成,我们不这样做的原因就是为了为大家演示Web Service的用途。你可以设想程序要访问远程服务器上的一个数据库,根据用户提交的不同信息,返回不同的数据,这时Web Service就大有用武之地了。

首先,我们还是使用Visual Studio.NET为我们生成一个空的Web Service项目。与前面不同的是,这一次,我们采用.NET中另一种重要的语言——Visual Basic.NET——来开发我们的Web Service,这没有什么特殊的意思,只不过想与大家一起体验一下全新的Visual Basic.NET语言。

打开Visual Studio.NET,点“New Project”,在Project Type中选择Visual Basic Project,在Template中选择ASP.NET Web Service,在下面输入工程名字GuessNumService,确定。

工程构造好后,我们可以看到一个设计页面,上面有两行字,点“click here to switch to code view”直接切换到代码编辑视图,开始我们的代码编写。设计页面主要是用于添加一些组件或数据库连接。

在代码视图中,我们可以看到一个被注释掉的HelloWorld函数,这其实是一个范例,告诉大家建立Web Service的方法,按照它的样子,我们输入下面的代码:

‘ <WebMethod()> 是给函数指定的一个属性(Attribute),指明这个函数将做为一个Web Service中的函数向外发布

<WebMethod()> Public Function GetTip(ByVal correctAnswer As String, ByVal userAnswer As String) As String

Dim i As Integer

Dim j As Integer

Dim a As Integer

Dim b As Integer

For i = 1 To 4

For j = 1 To 4

If Mid(correctAnswer, j, 1) = Mid(userAnswer, i, 1) Then

If j = i Then

a += 1 ‘VB程序员常常羡慕C++程序员这种简洁的写法,现在VB的程序员也可以用了!

Else

b += 1

End If

End If

Next

Next

下面用到的ToString()方法几乎是任何一种类型的数据都支持的类型转换函数

VB中如何把整型的4转成字符串型?STR(4)吧。在VB.NET中你可写成4.ToString()

GetTip = a.ToString() + “A” + b.ToString() + “B”

End Function

下面我们就可以来测试一下这个Web Service了,按F5键,Visual Studio.NET自动打开IE来测试这个Web Service,我们看到下面的画面:

Web Service

Web Service

这就是.NET为我们自动生成的服务测试页面,这个页面上列出了当前的Service1服务中提供的所有函数,现在只有一个GetTip()。同时这个页面上还提供了一个Service Description的链接,点击它,可以看到以XML描述的服务说明,我们称之为WSDL,即Web Service Description Language。

这里,我提醒大家把浏览器地址栏中的地址Copy下来,一会儿我们会用到它,在我的机器上这个地址是http://localhost/GuessNumService/Service1.asmx,从这里,我们也可以看出,Web Service的文件扩展名是asmx。

现在我们点击“GetTip”来测试这个Web服务,分别在correctAnswer和userAnswer两个文本框中输入数字,然后点击Invoke,结果就会以XML的形式返回。

比如我们分别输入3684和4628,这样的话,用户是猜对了一个数字“6”,还猜到了两个数字“4”和“8”,但放错了位置,所以返回的提示应该是1A2B,测试一下,果然如此!

测试Web Service

测试Web Service

Web Service XML返回结果

Web Service XML返回结果

Web Service 试验成功!我们终于可以开始构造一个完整的猜数字游戏了!

新建一个Visual C#的Windows Application(你也可以直接打开前面做好的GuessNum2,我们先在要做的只是在它基础上的修改),命名为GuessNumFinal,与前面做GuessNum2时一样设计游戏窗体,并以同样的方法,把GuessNum类加入GuessNumFinal名字空间,在Form1类中添加一个GuessNum的私有成员,然后添加窗体的Form1_Load和按钮的button1_Click方法。

下面要做的,就是要修改GuessNum类的GetTip方法,使它不再简单的返回一个“Wrong!”而是通过调用Web Service,把标准答案和用户输入提供给它,让它返回一个“xAyB”形式的提示字符串,然后再把这个字符串返回。当然,你也可以不修改写GuessNum,而是从它基础上派生一个新类,这个工作留给你自己去试验。

说的很容易,做起来呢?也不难!你不用担心要自己用WinSock写一个网络应用程序去访问Web Service,并自己对返回的XML文件进行处理,这些工作Visual Studio.NET已经帮我们做好了!

在Visual Studio.NET集成界面的右上角有一个Solution Explorer,我们用鼠标在里面的Reference上右键单击,然后选择“Add Web Reference”来添加一个对Web Service的引用。

添加Web引用

添加Web引用

在弹出的Add Web Reference对话框的地址栏中输入前面记录下来的地址,回车。等出现了Web Service的测试页面后,点击“Add Reference”按钮。

添加Web Reference

添加Web Reference

这时,我们就可以看到在Solution Explorer中新出现了一个Web Reference,里面有我们的Web Service。其实,我们通过Visual Studio.NET的帮助用这样简单的操作完成的是一系列的工作。首先是根据输入地址从服务器上获取WSDL,然后再根据WSDL的描述生成一个C#的代理类(Proxy Class),然后再把它添到工程中。

现在,我们就可以方便的使用这个类,来使我们的程序与Web Service联系起来,完成我们的需要的操作。

下面可以真正修改GuessNum的GetTip()的代码了。首先,我们在程序源代码的最前面加入:

using GuessNumFinal.localhost;

引用一下我们这个Web Service的代理类所在的名字空间,以方便我们后面代码的书写。(如果你不是新建了GuessNumFinal项目,而是在GuessNum2的基础上修改的话,请把上面的GuessNumFinal改成GuessNum2。)

接下来把GuessNum类的GetTip()方法改成如下的代码:

public string GetTip(string answer)

{

Service1 service = new Service1(); //GuessNumFinal.localhost名字空间中的Service1类生成一个对象

return service.GetTip(correctAnswer, answer); //呼叫Web Service,得到返回值后返回

}

最后,找到Form1_Load()方法中的

textBox2.Text = gn.GenerateRandomNumber();

把它改成下面的代码,我们不再需要偷看答案了!

textBox2.Text = “”;

gn.GenerateRandomNumber();

至此,我们程序终于完成了!按下F5运行程序,来体验一下自己用.NET编写的第一个游戏程序!

体验Microsoft .NET之结尾篇

我们的猜数字游戏做完了,我们的.NET之旅也将接近尾声。作为微软公司一个全新的平台,虽然目前有关.NET的争论还很多,但很多人还是相信.NET会在微软公司的大力支持下越来越成熟,.NET定将成为微软平台软件开发一个里程牌。

为了让大家更好的去了解和学习.NET,最后我在下面列出一些好的参考资料供大家参考:

1. 包含在.NET Framework SDK中的Samples and QuickStart Tutorials

2. 包含在Visual Studio.NET 中的Microsoft Visual Studio .NET Documentation

3. 微软公司网站,MSDN网站

4. http://www.cndot.net等国内外.NET技术网站