第八章 用C#写组件

2016-02-19 12:13 3 1 收藏

今天图老师小编给大家展示的是第八章 用C#写组件,精心挑选的内容希望大家多多支持、多多分享,喜欢就赶紧get哦!

【 tulaoshi.com - 编程语言 】

第八章    用C#写组件

    这一章关于用C#写组件。你学到如何写一个组件,如何编译它,且如何在一个客户程序中使用它。更深入一步是运用名字空间来组织你的应用程序。
    这章由两个主要大节构成:
    。你的第一个组件
    。使用名字空间工作

8.1  你的第一个组件
    到目前为止,在本书中提到的例子都是在同一个应用程序中直接使用一个类。类和它的使用者被包含在同一个执行文件中。现在我们将把类和使用者分离到组件和客户,它们分别位于不同的二进制文件中(可执行文件)。
    尽管你仍然为组件创建一个 DLL,但其步骤与用C++写一个COM组件差别很大。你很少涉及到底层结构。以下小节说明了如何构建一个组件以及使用到它的客户:

    。构建组件
    。编译组件
    。创建一个简单的客户应用程序

8.1.1  构建组件
    因为我是一个使用范例迷,我决定创建一个相关Web的类,以方便你们使用。它返回一个Web网页并储存在一个字符串
变量中,以供后来重用。所有这些编写都参考了.NET框架的帮助文档。
    类名为RequestWebPage;它有两个构造函数——  一个属性和一个方法。属性被命名为URL,且它储存了网页的Web地
址,由方法GetContent返回。这个方法为你做了所有的工作(见清单8.1)。

    清单 8.1   用于从Web服务器返回HTML网页的RequestWebPage 类

1: using System;
2: using System.Net;
3: using System.IO;
4: using System.Text;
5:
6: public class RequestWebPage
7: {
8:  private const int BUFFER_SIZE = 128;
9:  private string m_strURL;
10:
11:  public RequestWebPage()
12:  {
13:  }
14:
15:  public RequestWebPage(string strURL)
16:  {
17:   m_strURL = strURL;
18:  }
19:
20:  public string URL
21:  {
22:   get { return m_strURL; }
23:   set { m_strURL = value; }
24:  }
25:  public void GetContent(out string strContent)
26:  {
27:   // 检查 URL
28:   if (m_strURL == "")
29:    throw new ArgumentException("URL must be provided.");
30:
31:  WebRequest theRequest = (WebRequest) WebRequestFactory.Create(m_strURL);
32:   WebResponse theResponse = theRequest.GetResponse();
33:
34:   // 给回应设置字节缓冲区
35:   int BytesRead = 0;
36:   Byte[] Buffer = new Byte[BUFFER_SIZE];
37:
38:   Stream ResponseStream = theResponse.GetResponseStream();
39:   BytesRead = ResponseStream.Read(Buffer, 0, BUFFER_SIZE);
40:
41:   //使用 StringBuilder  以加速分配过程
42:   StringBuilder strResponse = new StringBuilder("");
43:   while (BytesRead != 0 )
44:   {
45:    strResponse.Append(Encoding.ASCII.GetString(Buffer,0,BytesRead));
46:    BytesRead = ResponseStream.Read(Buffer, 0, BUFFER_SIZE);
47:   }
48:
49:   // 赋给输出参数
50:   strContent = strResponse.ToString();
51:  }
52: }

    本应该利用无参数构造函数完成工作,但我决定在构造函数中初始化URL,这可能会很有用。当后来决定要改变URL
时——为了返回第二个网页,例如,通过URL属性的get和set访问标志使它被公开了。
    有趣的事始于GetContent方法。首先,代码对URL实行十分简单的检查,如果它不适合,就会引发一个
ArgumentException 异常。之后,我请求WebRequestFactory ,以创建一个基于传递给它的URL的WebRequest对象。
    因为我不想发送cookies、附加头和询问串等,所以立即访问WebResponse(第32行)。如果你需要请求上述任何的功
能,必须在这一行之前实现它们。
    第35和36行初始化一个字节缓冲区,它用于从返回流中读数据。暂时忽略StringBuilder 类,只要返回流中仍然有要
读的数据,while循环就会简单地重复。最后的读操作将返回零,因此结束了该循环。
    现在我想回到StringBuilder类。为什么用这个类的实例而不是简单地把字节缓冲区合并到一个字符串变量?看下面这
个例子:
    strMyString = strMyString + "some more text";
    这里很清楚,你正在拷贝值。常量 "some more text" 以一个字符串变量类型被加框,且根据加法操作创建了一个新
的字符串变量。接着被赋给了 strMyString。有很多次拷贝,是吗?
    但你可能引起争论
    strMyString += "some more text";
    不要炫耀这种行为。对不起,对于C#这是一个错误的答案。其操作完全与所描述的赋值操作相同。
    不涉及该问题的另外的途径是使用StringBuilder类。它利用一个缓冲区进行工作,接着,在没有发生我所描述的拷贝
行为的情况下,你进行追加、插入、删除和替换操作。这就是为什么我在类中使用它来合并那些读自缓冲区中的内容。
    该缓冲区把我带进了这个类中最后重要的代码片段——第45行的编码转换。它只不过涉及到我获得请求的字符集。
    最后,当所有的内容被读入且被转换时,我显式地从 StringBuilder请求一个字符串对象并把它赋给了输出变量。一
个返回值仍然会导致另外的拷贝操作。

8.1.2  编译组件
    到目前为止,你所做的工作与在正常应用程序的内部编写一个类没有什么区别。所不同的是编译过程。你必须创建一
个库而不是一个应用程序:
    csc /r:System.Net.dll /t:library /out:wrq.dll webrequest.cs
    编译开关/t:library  告诉C#编译,要创建一个库而不是搜寻一个静态 Main方法。同样,因为我正在使用
System.Net名字空间,所以必须引用 (/r:)它的库,这个库就是System.Net.dll。
    你的库命名为 wrq.dll,现在它准备用于一个客户应用程序。因为在这章中我仅使用私有组件工作,所以你不必把库
拷贝到一个特殊的位置,而是拷贝到客户应用程序目录。

8.1.3  创建一个简单的客户应用程序
    当一个组件被写成且被成功地编译时,你所要做的就是在客户应用程序中使用它。我再次创建了一个简单的命令行应
用程序,它返回了我维护的一个开发站点的首页(见清单8.2)。

    清单 8.2    用 RequestWebPage 类返回一个简单的网页

1: using System;
2:
3: class TestWebReq
4: {
5:  public static void Main()
6:  {
7:   RequestWebPage wrq = new RequestWebPage();
8:   wrq.URL = "http://www.alphasierrapapa.com/iisdev/";
9:
10:   string strResult;
11:   try
12:   {
13:    wrq.GetContent(out strResult);
14:   }
15:   catch (Exception e)
16:   {
17:    Console.WriteLine(e);
18:    return;
19:   }
20:
21:   Console.WriteLine(strResult);
22:  }
成员
    
    注意,我已经在一个try catch语句中包含了对 GetContent的调用。其中的一个原因是GetContent可能引发一个
ArgumentException异常。此外,我在组件内部调用的.NET框架类也可以引发异常。因为我不能在类的内部处理这些异常,
所以我必须在这里处理它们。
    其余的代码只不过是简单的组件使用——调用标准的构造函数,存取一个属性,并执行一个方法。但等一下:你需要
注意何时编译应用程序。一定要告诉编译器,让它引用你的新组件库DLL:
    csc /r:wrq.dll wrclient.cs
    现在万事俱备,你可以测试程序了。输出结果会滚屏,但你可以看到应用程序工作。使用了常规的表达式,你也可以
增加代码,以解析返回的HTML,并依据你个人的喜好,提取信息。我预想会使用到这个类新版本的SSL(安全套接字层),
用于ASP+网

来源:http://www.tulaoshi.com/n/20160219/1600242.html

延伸阅读
《刺客信条2》图文攻略及心得第八章 第八章 1485年 跟踪目标 然后设法潜入教堂 这边会发现那人要暗杀一位叫Doge Mocenigo的主教并派人取代   但问题是主教不好接近,于是想到达文西的鸟点子,当鸟人试飞 但飞行器飞不远,后来达文西想到热气上升的原理,于是ezio 得先除掉屋顶上大部份的弓箭兵,然后再派手下去点火制造热气上升能 &...
《最终幻想13》详细攻略手记:第八章 第八章 歓楽都市 ノーチラス 歓楽都市ノーチラス/観光艇ステーション 奖杯Instrument of Shame入手~~ 剧情后转到香草一行~~走盘调整装备和OPTIMA后做个记录~~NPC还真多= =~~四处看看对话后来到目的地发生剧情~~继续前进来到目的地发生剧情~~ 歓楽都市ノーチラス/フェスティバロード 四处看...
x360《镜之边缘》视频攻略 第八章 第八章 《66663》平衡设计师退出团队 或转向镜之边缘2     最近,《66663》的核心游戏平衡设计师Alan Kertz在其个人Twitter(ID:Demize99)上宣布了他不再是《66663》开发团队中的一份子了。     当你听到这个消息之请按不要有任何恐怖,Alan Kertz谈及到:“...
标签: 手机游戏
《星际传奇》第八章精英难度关卡通关技巧详解 《星际传奇》中,第八章精英关卡相对于普通关卡有了更高的难度,那么第八章精英关卡该怎么过,三星该怎么拿,有什么好的方法技巧呢,下面一起来看看吧。 一,杀意 与普通的杀意一样,沿途的机枪塔、导弹塔、电塔依旧是主要的伤害来源,在有杂兵和炮塔的前提下,优先清除炮塔则是优先要...
《第一圣殿骑士》图文流程攻略(第八章Ascalon Citadel) 这一关又是个陷阱重重的关卡,下干掉一开始的几个敌人后两个人一起启动机关开门。 接下来到这个满是火的房间,看着那些时而喷火时而停的地方,看准时机通过, 像这种地上有管子却不喷火的,按住ctrl查看下就发现地上有陷阱了,不要踩上去。 通过火焰后来到有两个推杆的房间...

经验教程

90

收藏

58
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部