动态网站制作指南



当前位置 > 网站建设学院 > 网络编程 > ASP文摘 Rss
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket

<展现C#> 第九章 配置和调度


发表日期:2000-11-2


第九章  配置和调度

    在上一章,你学到如何创建一个通用语言运行时(CLR)组件,且如何在一个简单的测试应用程序中使用它。虽然CLR组件就要准备装载了,但你还是应该思考以下技术之一:
  。条件编译
  。文档注释
  。代码版本化

9.1   条件编译  
    没有代码的条件编译功能,我就不能继续工作。条件编译允许执行或包括基于某些条件的代码;例如,生成应用程序
的一个查错(DEBUG)版本、演示(DEMO)版本或零售(RELEASE)版本。可能被包括或被执行的代码的例子为许可证代
码、 屏幕保护或你出示的任何程序。
    在C#中,有两种进行条件编译的方法:
    。预处理用法
    。条件属性
9.1.1   预处理用法
    在C++中,在编译器开始编译代码之前,预处理步骤是分开的。在C#中,预处理被编译器自己模拟—— 没有分离的预
处理。它只不过是条件编译。
    尽管C#编译器不支持宏,但它具有必需的功能,依据符号定义的条件,排除和包括代码。以下小节介绍了在C#中受支
持的各种标志,它们与在C++中看到的相似。
    。定义符号
    。依据符号排除代码
    。引起错误和警告
9.1.1.1  定义符号
    你不能使用随C#编译器一起的预处理创建“define 标志:符号:定义 ”宏,但是,你仍可以定义符号。根据某些符号
是否被定义,可以排除或包括代码。
    第一种定义符号的办法是在C#源文件中使用 #define标志:
    #define DEBUG
    这样定义了符号DEBUG,且范围在它所定义的文件内。请注意,必须要先定义符号才能使用其它语句。例如,以下代码
段是不正确的:

    using System;
    #define DEBUG

    编译器将标记上述代码为错误。你也可以使用编译器定义符号(用于所有的文件):
    csc /define:DEBUG mysymbols.cs
    如果你想用编译器定义多种符号,只需用分号隔开它们:
    csc /define:RELEASE;DEMOVERSION mysymbols.cs
    在C#源文件中,对这两种符号的定义分为两行 #define 标志。
    有时,你可能想要取消源文件中(例如,较大项目的源文件)的某种符号。可以用 #undef 标志取消定义:
    #undef DEBUG
    #define的“定义标志:符号: 定义”规则同样适用于#undef:  它的范围在自己定义的文件之内,要放在任何语句如
using语句之前。
    这就是全部有关用C#预处理定义符号和取消定义符号所要了解的知识。以下小节说明如何使用符号有条件地编译代
码。

9.1.1.2 依据符号包括和排除代码
    最重要的“if标志:符号:包括代码”方式的目的为,依据符号是否被定义,有条件地包括和排除代码。清单9.1  包含
了已出现过的源码,但这次它依据符号被有条件地编译。

    清单 9.1  利用 #if 标志有条件地包括代码

1: using System;
2:
3: public class SquareSample
4: {
5: public void CalcSquare(int nSideLength, out int nSquared)
6: {
7:  nSquared = nSideLength * nSideLength;
8: }
9:
10: public int CalcSquare(int nSideLength)
11: {
12:  return nSideLength*nSideLength;
13: }
14: }
15:
16: class SquareApp
17: {
18: public static void Main()
19: {
20:  SquareSample sq = new SquareSample();
21:  
22:  int nSquared = 0;
23:
24: #if CALC_W_OUT_PARAM
25:  sq.CalcSquare(20, out nSquared);
26: #else
27:  nSquared = sq.CalcSquare(15);
28: #endif
29:  Console.WriteLine(nSquared.ToString());
30: }
31: }

    注意,在这个源文件中没有定义符号。当编译应用程序时,定义(或取消定义)符号:
    csc /define:CALC_W_OUT_PARAM square.cs
    根据“ if标志:符号:包括代码”的符号定义,不同的 CalcSquare 被调用了。用来对符号求值的模拟预处理标志为
#if、 #else和 #endif。它们产生的效果就象C#相应的if 语句那样。你也可以使用逻辑“与”(&&)、逻辑“或”
(&brvbar;&brvbar;)以及“否”(!)。它们的例子显示在清单9.2 中。

    清单 9.2  使用#elif 在#if标志中创建多个分支

1: // #define DEBUG
2: #define RELEASE
3: #define DEMOVERSION
4:
5: #if DEBUG
6: #undef DEMOVERSION
7: #endif
8:
9: using System;
10:
11: class Demo
12: {
13: public static void Main()
14: {
15: #if DEBUG
16:  Console.WriteLine("Debug version");
17: #elif RELEASE && !DEMOVERSION
18:  Console.WriteLine("Full release version");
19: #else
20:  Console.WriteLine("Demo version");
21: #endif
22: }
23: }

    在这个“if标志:符号:包含代码”例子中,所有的符号都在C#源文件中被定义。注意第6行#undef语句增加的那部分。
由于不编译DEBUG代码的DEMO版本(任意选择),我确信它不会被某些人无意中定义了,而且总当DEBUG被定义时,就取消
DEMO版本的定义。
    接着在第15~21行,预处理符号被用来包括各种代码。注意#elif标志的用法,它允许你把多个分支加到#if 标志。该
代码运用逻辑操作符“&&”和非操作符“!”。也可能用到逻辑操作符“&brvbar;&brvbar;”,以及等于和不等于操作
符。

9.1.1.3 引起错误并警告
    另一种可能的“警告  标志错误  标志”预处理标志的使用,是依据某些符号(或根本不依据,如果你这样决定)引
起错误或警告。各自的标志分别为 #warning和#error,而清单9.3 演示了如何在你的代码中使用它们。
    清单 9.3   使用预处理标志创建编译警告和错误

1: #define DEBUG
2: #define RELEASE
3: #define DEMOVERSION
4:
5: #if DEMOVERSION && !DEBUG
6: #warning You are building a demo version
7: #endif
8:
9: #if DEBUG && DEMOVERSION
10: #error You cannot build a debug demo version
11: #endif
12:
13: using System;
14:
15: class Demo
16: {
17: public static void Main()
18: {
19:  Console.WriteLine("Demo application");
20: }
21: }

    在这个例子中,当你生成一个不是DEBUG版本的DEMO版本时,就发出了一个编译警告(第5行~第7行)。当你企图生成
一个DEBUG DEMO版本时,就引起了一个错误,它阻止了可执行文件的生成。对比起前面只是取消定义令人讨厌的符号的例
子,这些代码告诉你,“警告  标志错误 标志”企图要做的工作被认为是错误的。这肯定是更好的处理办法。
9.1.1.4  条件属性
    C++的预处理也许最经常被用来定义宏,宏可以解决一种程序生成时的函数调用,而却不能解决另一种程序生成时的任
何问题。这些例子包括 ASSERT和TRACE 宏,当定义了DEBUG符号时,它们对函数调用求值,当生成一个RELEASE版本时,求
值没有任何结果。

    当了解到宏不被支持时,你也许会猜测,条件功能已经消亡了。幸亏我可以报道,不存在这种情况。你可以利用条件
属性,依据某些已定义符号来包括方法。:

     [conditional("DEBUG")]
     public void SomeMethod() { }

    仅当符号DEBUG被定义时,这个方法被加到可执行文件。并且调用它,就象
    SomeMethod();

    当该方法不被包括时,它也被编译器声明。功能基本上和使用C++条件宏相同。
    在例子开始之前,我想指出,条件方法必须具有void的返回类型,不允许其它返回类型。然而,你可以传递你想使用
的任何参数。
    在清单9.4 中的例子演示了如何使用条件属性重新生成具有C++的TRACE宏一样的功能。为简单起见,结果直接输出到
屏幕。你也可以根据需要把它定向到任何地方,包括一个文件。

    清单 9.4  使用条件属性实现方法

1: #define DEBUG
2:
3: using System;
4:
5: class Info
6: {
7: [conditional("DEBUG")]
8: public static void Trace(string strMessage)
9: {
10:  Console.WriteLine(strMessage);
11: }
12:
13: [conditional("DEBUG")]
14: public static void TraceX(string strFormat,params object[] list)
15: {
16:  Console.WriteLine(strFormat, list);
17: }
18: }
19:
20: class TestConditional
21: {
22: public static void Main()
23: {
24:  Info.Trace("Cool!");
25:  Info.TraceX("{0} {1} {2}","C", "U", 2001);
26: }
27: }

    在Info类中,有两个静态方法,它们根据DEBUG符号被有条件地编译:Trace,接收一个参数,而TraceX则接收n个参
数。Trace的实现直接了当。然而,TraceX实现了一个你从没有见过的关键字:params。
    params 关键字允许你指定一个方法参数,它实际上接收了任意数目的参数。其类似C/C++的省略参数。注意,它必须
是方法调用的最后一个参数,而且在参数列表中,你只能使用它一次。毕竟,它们的局限性极其明显。
    使用params 关键字的意图就是要拥有一个Trace方法,该方法接收一个格式字符串以及无数个置换对象。幸好,还有
一个支持格式字符串和对象数组的 WriteLine方法(第16行)。
    这个小程序产生的哪一个输出完全取决于DEBUG是否被定义。当DEBUG符号被定义时,方法都被编译和执行。如果DEBUG
不被定义,对Trace和TraceX的调用也随之消失。
    条件方法是给应用程序和组件增加条件功能的一个真正强大的手段。用一些技巧,你就可以根据由逻辑“或”
(&brvbar;&brvbar;)以及逻辑“与”(&&)连接起来的多个符号,生成条件方法。然而,对于这些方案,我想给你推荐C#
文档。
  
9.2  在xml中的文档注释
    很多程序员根本不喜欢的一项任务就是写作,包括写注释和写文档。然而,有了C#,你就找到改变老习惯的好理由:
你可以用代码的注释自动生成文档。
    由编译器生成的输出结果是完美的XML。它可以作为组件文档的输入被使用,以及作为显示帮助并揭示组件内部细节的
工具。例如, Visual Studio 7 就是这样一种工具。
    这一节专门为你说明如何最好地运用C#的文档功能。该例子涉及的范围很广,所以你不能有这样的借口,说它过于复
杂,以至很难领会如何加入文档注释。文档是软件极其重要的一部分,特别是要被其他开发者使用的组件的文档。
    在以下小节中,文档注解用来说明RequestWebPage 类。我已分别在以下几小节中做出解释:
    。描述一个成员
    。添加备注和列表
    。提供例子
    。描述参数
    。描述属性
    。编译文档


9.2.1  描述一个成员
    第一步,为一个成员添加一个简单的描述。你可以用 <summary> 标签这样做:
/// <summary>This is .... </summary>


    每一个文档注释起始于由三个反斜杠组成的符号“///”。你可以把文档注释放在想要描述的成员之前:

/// <summary>Class to tear a Webpage from a Webserver</summary>

public class RequestWebPage

    使用<para>和 </para>标签,为描述添加段落。用<see>标签引用其它已有了注释的成员。
/// <para>Included in the <see cref="RequestWebPage"/> class</para>

    增加一个链接到RequestWebPage类的描述。注意,用于标签的语法是XML语法,这意味着标签大写化的问题,而且标签
必须正确地嵌套。
    当为一个成员添加文档时,另一个有趣的标签是<seealso> 。它允许你描述可能使读者非常感兴趣的其它话题。

/// <seealso cref="System.Net"/>

    前面的例子告诉读者,他可能也想查阅System.Net 名字空间的文档。你一定要给超出当前范围的项目规定一个完全资
格名。
    作为许诺,清单9.5 包含 RequestWebPage类中正在工作的文档的所有例子。看一下如何使用标签以及嵌套如何为组件
产生文档。

    清单 9.5  利用 <summary>, <see>, <para>, and <seealso> 标签描述一个成员

1: using System;
2: using System.Net;
3: using System.IO;
4: using System.Text;
5:
6: /// <summary>Class to tear a Webpage from a Webserver</summary>
7: public class RequestWebPage
8: {
9: PRivate const int BUFFER_SIZE = 128;
10:
11: /// <summary>m_strURL stores the URL of the Webpage</summary>
12: private string m_strURL;
13:
14: /// <summary>RequestWebPage() is the constructor for the class
15: /// <see cref="RequestWebPage"/> when called without arguments.</summary>
16: public RequestWebPage()
17: {
18: }
19:
20: /// <summary>RequestWebPage(string strURL) is the constructor for the class
21: /// <see cref="RequestWebPage"/> when called with an URL as parameter.</summary>
22: public RequestWebPage(string strURL)
23: {
24:  m_strURL = strURL;
25: }
26:
27: public string URL
28: {
29:  get { return m_strURL; }
30:  set { m_strURL = value; }
31: }
32:
33: /// <summary>The GetContent(out string strContent) method:
34: /// <para>Included in the <see cref="RequestWebPage"/> class</para>
35: /// <para>Uses variable <see cref="m_strURL"/></para>
36: /// <para>Used to retrieve the content of a Webpage. The URL
37: ///  of the Webpage (including http://) must already be
38: ///  stored in the private variable m_strURL.
39: ///  To do so, call the constructor of the RequestWebPage
40: ///  class, or set its property <see cref="URL"/> to the URL string.</para>
41: /// </summary>
42: /// <seealso cref="System.Net"/>
43: /// <seealso cref="System.Net.WebResponse"/>
44: /// <seealso cref="System.Net.WebRequest"/>
45: /// <seealso cref="System.Net.WebRequestFactory"/>
46: /// <seealso cref="System.IO.Stream"/>
47: /// <seealso cref="System.Text.StringBuilder"/>
48: /// <seealso cref="System.ArgumentException"/>
49:
50: public bool GetContent(out string strContent)
51: {
52:  strContent = "";
53:  // ...
54:  return true;
55: }
56: }

9.2.2  添加备注和列表
     <remarks> 标签是规定大量文档的地方。与之相比, <summary>只仅仅规定了成员的简短描述。
     你不限于只提供段落文本(使用<para>标签)。例如,你可以在备注部分包含bulleted(和有限偶数)列表
(list):

///  <list type="bullet">
///  <item>Constructor
///   <see cref="RequestWebPage()"/> or
///   <see cref="RequestWebPage(string)"/>
///  </item>
///  </list>

    这个list有一项(item),且该item引用了两个不同的构造函数描述。你可以根据需要,任意往list item中添加内
容。
    另一个在备注部分很好用的标签是<paramref>。例如,你可以用<paramref>来引用和描述传递给构造函数的参数:

/// <remarks>Stores the URL from the parameter /// <paramref name="strURL"/> in
/// the private variable <see cref="m_strURL"/>.</remarks>
public RequestWebPage(string strURL)

    在清单9.6中,你可以看到所有的这些以及前面的标签正在起作用。

    清单9.6 为文档添加一个备注和bullet list

1: using System;
2: using System.Net;
3: using System.IO;
4: using System.Text;
5:
6: /// <summary>Class to tear a Webpage from a Webserver</summary>
7: /// <remarks>The class RequestWebPage provides:
8: /// <para>Methods:
9: ///  <list type="bullet">
10: ///  <item>Constructor
11: ///   <see cref="RequestWebPage()"/> or
12: ///   <see cref="RequestWebPage(string)"/>
13: ///  </item>
14: ///  </list>
15: /// </para>
16: /// <para>Properties:
17: ///  <list type="bullet">
18: ///  <item>
19: ///   <see cref="URL"/>
20: ///  </item>
21: ///  </list>
22: /// </para>
23: /// </remarks>
24: public class RequestWebPage
25: {
26: private const int BUFFER_SIZE = 128;
27:
28: /// <summary>m_strURL stores the URL of the Webpage</summary>
29: private string m_strURL;
30:
31: /// <summary>RequestWebPage() is the constructor for the class
32: /// <see cref="RequestWebPage"/> when called without arguments.</summary>
33: public RequestWebPage()
34: {
35: }
36:
37: /// <summary>RequestWebPage(string strURL) is the constructor for the class
38: /// <see cref="RequestWebPage"/> when called with an URL as parameter.</summary>
39: /// <remarks>Stores the URL from the parameter <paramref name="strURL"/> in
40: /// the private variable <see cref="m_strURL"/>.</remarks>
41: public RequestWebPage(string strURL)
42: {
43:  m_strURL = strURL;
44: }
45:
46: /// <remarks>Sets the value of <see cref="m_strURL"/>.
47: ///  Returns the value of <see cref="m_strURL"/>.</remarks>
48: public string URL
49: {
50:  get { return m_strURL; }
51:  set { m_strURL = value; }
52: }
53:
54: /// <summary>The GetContent(out string strContent) method:
55: /// <para>Included in the <see cref="RequestWebPage"/> class</para>
56: /// <para>Uses variable <see cref="m_strURL"/></para>
57: /// <para>Used to retrieve the content of a Webpage. The URL
58: ///  of the Webpage (including http://) must already be
59: ///  stored in the private variable m_strURL.
60: ///  To do so, call the constructor of the RequestWebPage
61: ///  class, or set its property <see cref="URL"/> to the URL string.</para>
62: /// </summary>
63: /// <remarks>Retrieves the content of the Webpage specified in
64: /// the property<see cref="URL"/> and hands it over to the out
65: /// parameter <paramref name="strContent"/>.
66: /// The method is implemented using:
67: /// <list>
68: ///  <item>The <see cref="System.Net.WebRequestFactory.Create"/>method.</item>
69: ///  <item>The <see cref="System.Net.WebRequest.GetResponse"/> method.</item>
70: ///  <item>The <see cref="System.Net.WebResponse.GetResponseStream"/>method</item>
71: ///  <item>The <see cref="System.IO.Stream.Read"/> method</item>
72: ///  <item>The <see cref="System.Text.StringBuilder.Append"/> method</item>
73: ///  <item>The <see cref="System.Text.Encoding.ASCII"/> property together with its
74: ///  <see cref="System.Text.Encoding.ASCII.GetString"/> method</item>
75: ///  <item>The <see cref="System.Object.ToString"/> method for the
76: ///  <see cref="System.IO.Stream"/> object.</item>
77: /// </list>
78: /// </remarks>
79: /// <seealso cref="System.Net"/>
80: public bool GetContent(out string strContent)
81: {
82:  strContent = "";
83:  // ...
84:  return true;
85: }
86: }

9.2.3 提供例子
    要想说明一个对象和方法的用法,最好的办法是提供优秀源代码的例子。因此,不要诧异文档注释也有用于声明例子
的标签: <example> and <code>。 <example>标签包含了包括描述和代码的整个例子,而 <code> 标签仅包含了例子的代
码(令人惊讶)。
    清单9.7 说明如何实现代码例子。包括的例子用于两个构造函数。你必须给GetContent方法提供例子。

    清单.7  利用例子解释概念

1: using System;
2: using System.Net;
3: using System.IO;
4: using System.Text;
5:
6: /// <summary>Class to tear a Webpage from a Webserver</summary>
7: /// <remarks> ... </remarks>
8: public class RequestWebPage
9: {
10: private const int BUFFER_SIZE = 12


关注此文的读者还看过:
·2012-5-22 18:24:36 <展现C#> 第八章 用C#写组件
·2012-5-22 18:16:30 NET真面目(下)
·2012-5-22 18:06:43 程序员:增加编程经验的3种途径
·2012-5-22 17:48:43 如何在98上支持cgi,php,asp,mysql
·2012-5-22 17:45:44 安全维护 IIS asp 站点的高级技巧
·2012-5-22 17:39:44 .NET语言的选择 
·2012-5-22 17:38:58 Microsoft .NET 框架常见问题(一)
·2012-5-22 17:37:08 构建高负载Web服务器
·2012-5-22 17:31:23 动态网页技术--CGI:ASP:JSP:PHP(2)
站长推荐 PS笔刷下载 在线翻译 系统进程 广告代码
  发表评论
姓 名: 验证码:
内 容:
教程搜索服务
ASP源码推荐
·Net112企业建站系统 v1.0
·PJBlog2 v2.7 build 04 伪静态H
·乐彼外贸英文网店系统(56770 ES
·YFCMS网站管理系统 v5.0
·零点站点管理系统 v2.1
·7cbbs 论坛 v3.36
·闪客Flash整站
·飞跃网络FLASH音乐程序 v2.0
·戏子博客 v1.0
·孤独BLOG系统
·零点网络虚拟主机域名系统 精华
·乌有之乡留言系统 v1.0
项目外包信息
·寻会php的程序员外包网站
·派桑网络-网络营销专家
·汽车配件网站制作 50000元
·整站SEO优化
·课件门户网程序
·求长期合作网站设计制作高手
·公司网站重新改版 8000元
·asp企业网站小改动
·网站flash片头
·文化传播公司网站设计稿
·UI界面设计
·产品外观改版设计 15000元
·照明灯具网站设计 10000元
·求长期合作网站设计制作高手
·做B2C网站 20000元
发布信息 浏览信息
邮件订阅服务
输入你的邮件地址,你将不会错过任何关于<ASP文摘>的内容


网络编程文章分类
ASP教程
ASP实例
ASP技巧
ASP文摘
PHP教程
PHP技巧
PHP实例
PHP文摘
JSP教程
JSP技巧
JSP实例
JSP文摘
ASP.NET教程
ASP.NET技巧
ASP.NET实例
ASP.NET应用
xml教程
xsl教程
xml技巧
C#教程
C#应用
Delphi教程
Perl教程
Shell教程
Ajax教程
Visual Basic教程
Java教程
J2EE/J2ME教程
C/C++教程
移动解决方案
移动短信技术
移动行业动态
软件工程
WordPress
Android开发
站长工具:Google PR查询|Alexa排名查询|网站速度测试|CSS在线编辑器|OPEN参数生成器|弹出式窗口代码产生器|密码登录生成器|在线按钮生成器|Meta标签生成器|邮箱图标在线生成|多色彩特效字代码生成器|网页代码调试器|在线FTP登陆|Flash取色器|配色代码对照表|配色辞典|CSS生成器|CSS在线压缩|广告代码|框架网页代码生成器|js/vbs加密|md5加密|进制转换|UTF-8 转换工具|在线调色板|Html转换js|Html转换asp|Html转换php|Html转换perl
实用工具:汉字翻译拼音|拼音字典|在线翻译|天气预报|火星文|在线网速测试|符号对照表|个税计算|理财工具|黄金价格|购房银行按揭利率计算|汇率查询|经典小工具|汉字简繁转换|普通单位换算|公制单位换算|生辰老黄历|国内电话区号|国家代码与域名缩写|文字加密解密|元素周期表|健康查询|世界时间|全国各地车牌查询|全国车辆交通违章查询|万年历|二十四节气|汉字横竖排版|手机号码查询|计算器|ip搜索|酒店预订|机票预订
广告刊登 | 版权声明 | 联系我们 | 加入收藏 | RSS订阅
Copyright © 2000-2012 www.knowsky.com All rights reserved | 沪ICP备05001343号