新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论.NET,C#,ASP,VB技术
    [返回] 中文XML论坛 - 专业的XML技术讨论区计算机技术与应用『 Dot NET,C#,ASP,VB 』 → <展现 C#> (rainbow 翻译)- 第九章 配置和调度 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 10278 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: <展现 C#> (rainbow 翻译)- 第九章 配置和调度 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     admin 帅哥哟,离线,有人找我吗?
      
      
      
      威望:9
      头衔:W3China站长
      等级:计算机硕士学位(管理员)
      文章:5255
      积分:18406
      门派:W3CHINA.ORG
      注册:2003/10/5

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给admin发送一个短消息 把admin加入好友 查看admin的个人资料 搜索admin在『 Dot NET,C#,ASP,VB 』的所有贴子 点击这里发送电邮给admin  访问admin的主页 引用回复这个贴子 回复这个贴子 查看admin的博客楼主
    发贴心情 <展现 C#> (rainbow 翻译)- 第九章 配置和调度


    发信人: wuxq (很想好好休息), 信区: DotNET        
    标  题: <展现 C#> (rainbow 翻译)- 第九章 配置和调度
    发信站: BBS 水木清华站 (Mon Apr 30 13:53:29 2001)

    第九章  配置和调度
        在上一章,你学到如何创建一个通用语言运行时(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 语句那样。你也可以使用逻辑“与”(&&)、逻辑“或”(||)以及“否”(!)。
    它们的例子显示在清单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 标志。该代码运用逻辑操作符“&&”和非操作符“!”。也可
    能用到逻辑操作符“||”,以及等于和不等于操作符。
    9.1.1.3 引起错误并警告
        另一种可能的“警告  标志错误  标志”预处理标志的使用,是依据某些符号(或
    根本不依据,如果你这样决定)引起错误或警告。各自的标志分别为 #warning和#erro
    r,而清单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的调用也随之消失。
        条件方法是给应用程序和组件增加条件功能的一个真正强大的手段。用一些技巧,
    你就可以根据由逻辑“或”(||)以及逻辑“与”(&&)连接起来的多个符号,生成条件
    方法。然而,对于这些方案,我想给你推荐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 cl
    ass
    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.</pa
    ra>
    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>标签)。例如,你可以在备注部分包含bul
    leted(和有限偶数)列表(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 cl
    ass
    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.</pa
    ra>
    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"/>met
    hod</item>
    71: ///  <item>The <see cref="System.IO.Stream.Read"/> method</item>
    72: ///  <item>The <see cref="System.Text.StringBuilder.Append"/> method</it
    em>
    73: ///  <item>The <see cref="System.Text.Encoding.ASCII"/> property togethe
    r 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 说明如何实现代码例子。包括的例子用于两个构造函数。你必须给GetCon
    tent方法提供例子。
        清单.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

    --

    ※ 来源:·BBS 水木清华站 smth.org·[FROM: 166.111.215.13]
    上一篇
    返回上一页
    回到目录
    回到页首


       收藏   分享  
    顶(0)
      




    ----------------------------------------------

    -----------------------------------------------

    第十二章第一节《用ROR创建面向资源的服务》
    第十二章第二节《用Restlet创建面向资源的服务》
    第三章《REST式服务有什么不同》
    InfoQ SOA首席编辑胡键评《RESTful Web Services中文版》
    [InfoQ文章]解答有关REST的十点疑惑

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2004/11/9 2:25:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 Dot NET,C#,ASP,VB 』的所有贴子 点击这里发送电邮给Google AdSense  访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/4/20 9:54:37

    本主题贴数1,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    78.125ms