国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

.NET2005提供的Code Snippets看代碼復(fù)用

2019-11-18 12:01:58
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

  首先說(shuō)明這里的代碼復(fù)用指的是狹義的源代碼的復(fù)用,而不是廣義的黑盒復(fù)用和白合復(fù)用所指的代碼復(fù)用,所以文中所說(shuō)的代碼復(fù)用都默認(rèn)都是指前者所指的源代碼的復(fù)用。
  
  我們知道在程序設(shè)計(jì)中復(fù)用代碼并不是一件輕易的事情,其實(shí)每段代碼的編寫,都是通過(guò)一定的思考的,當(dāng)然考慮的程度與其解決的問(wèn)題的難度有關(guān)。我們很忌諱在一個(gè)工程中重復(fù)使用相同的源代碼,假如出現(xiàn)這樣的情況很多時(shí)候就是程序結(jié)構(gòu)設(shè)計(jì)本身的不合理了。可是對(duì)于一個(gè)developer或一個(gè)PRodUCt team,源代碼的邏輯(主要是執(zhí)行邏輯,而不是業(yè)務(wù)邏輯)在不同項(xiàng)目或同一項(xiàng)目不同版本中很可能需要復(fù)用,而這種復(fù)用很多時(shí)候又是很難抽象成廣義的代碼復(fù)用的。于是我們不得不ctrl+c & ctrl+v,這是一個(gè)好辦法,也確實(shí)能為我們節(jié)省很多的時(shí)間,可是這樣同時(shí)也會(huì)帶來(lái)很多的問(wèn)題。假如被復(fù)用的代碼是近期所寫的,我們一般對(duì)其很熟悉,ctrl+v時(shí)心理也很有底。可是對(duì)于編寫了很久的代碼,我們?cè)赾trl+v就不得不考慮一下代碼是不時(shí)完全合適被復(fù)用了。更多的時(shí)候我們還需要對(duì)復(fù)用代碼做一些小的修改,最簡(jiǎn)單的修改莫過(guò)于把變量名改來(lái)適合當(dāng)前代碼的上下文。
  
  假如有這樣復(fù)用過(guò)代碼的人可能會(huì)有一種感覺(jué),我總是不知道哪個(gè)源碼文件里的代碼snippet是我覺(jué)得解決這個(gè)邏輯最好的@_@,因?yàn)槊看蝐trl+v后或多或少又會(huì)把代碼做一些小的改動(dòng),或是修補(bǔ)不足或是增加功能。非凡是修補(bǔ)了不足后假如能保留下來(lái)以做再次復(fù)用就好了,可是很多時(shí)候這些越來(lái)越優(yōu)秀的代碼snippet卻仍然分布在某個(gè)項(xiàng)目的某個(gè)文件中。于是我們發(fā)現(xiàn)有些小工具可以用來(lái)幫助我們保存代碼snippet,比如前些天有人開發(fā)的類似CodeLib什么的。
  
  今天在用VS.NET 2005的時(shí)候,發(fā)現(xiàn)tools菜單里有一個(gè)Code Snippets Manager(或者用Ctrl+k,Ctrl+b呼出)。打開看了一下,第一感覺(jué)就是一個(gè)代碼模版治理嘛,看看了些預(yù)置的snippet,居然都是些很簡(jiǎn)單的類似if語(yǔ)句結(jié)構(gòu)、for語(yǔ)句結(jié)構(gòu)、do語(yǔ)句結(jié)構(gòu)、while語(yǔ)句結(jié)構(gòu)等,覺(jué)得真是沒(méi)有意思,難道微軟要我們用鼠標(biāo)來(lái)編程嗎?繼續(xù)往后翻,發(fā)現(xiàn)了幾個(gè)比較復(fù)雜的snippets,有的有一屏那么多的代碼。其實(shí)代碼多少不是snippet的重要的問(wèn)題了,而是這些snippet在插入IDE后,可以根據(jù)其在文件里的命令定義,產(chǎn)生如下圖所示的自動(dòng)添補(bǔ)提示功能:
  
.NET2005提供的Code Snippets看代碼復(fù)用

  在圖中黃底黑字區(qū)域內(nèi)編輯完后按Tab,其下面的虛線框里的內(nèi)容會(huì)同步的更新。這樣的功能為我們收集并復(fù)用源代碼提供了很便利的支持,這個(gè)snippet是以xml格式保存的,只是whidbey beta1里面還沒(méi)沒(méi)有提供snippet文件的可視化編輯器,不過(guò)xml本身在VS.NET里也不難寫。上圖示例的代碼文件如下:
  
  <CodeSnippet Format="1.0.0">
  <Header>
    <Title>"named" iterator / indexer pair</Title>
    <Shortcut>iterindex</Shortcut>
    <Description>Implement a "named" iterator / indexer pair, using a nested class</Description>
    <SnippetTypes>
      <SnippetType>EXPansion</SnippetType>
    </SnippetTypes>
  </Header>
  <Snippet>
    <Declarations>
      <Literal>
        <ID>type</ID>
        <Default>ElementType</Default>
        <ToolTip>Type to return from iterator / indexer</ToolTip>
      </Literal>
      <Literal>
        <ID>name</ID>
        <Default>MyView</Default>
        <ToolTip>Name of the iterator/indexer pair</ToolTip>
      </Literal>
      <Literal Editable="false">
        <ID>outer</ID>
        <Default>MyOuterClass</Default>
        <Function>ClassName()</Function>
      </Literal>
      <Literal Editable="false">
        <ID>SystemCollectionsGenericIEnumeratorG</ID>
        <!-- Function>ShortName(System.IEnumerator)</Function -->
        <Default>System.Collections.Generic.IEnumerator</Default>
      </Literal>
      <Literal Editable="false">
        <ID>SystemNotImplementedException</ID>
        <!-- Function>ShortName(System.NotImplementedException)</Function -->
        <Default>System.NotImplementedException</Default>
      </Literal>
    </Declarations>
    <Code Language="csharp" Format="CData"><![CDATA[public $name$Impl $name$
    {
      get
      {
        return new $name$Impl(this);
      }
    }
  
    public class $name$Impl
    {
      readonly $outer$ _outer;
  
      internal $name$Impl($outer$ mc)
      {
        this._outer = mc;
      }
  
      // A Length property isn't required, but it's often useful.
      public int Length { get { return 1; } }
  
      public $type$ this[int index]
      {
        get
        {
          //
          // TODO: implement indexer here
          //
          // you have full access to $outer$ privates.
          //
          $end$throw new System.NotImplementedException();
          return default($type$);
        }
      }
  
      public $SystemCollectionsGenericIEnumeratorG$<$type$> GetEnumerator()
      {
        // TODO: provide an appropriate implementation here
        for (int i = 0; i < this.Length; i++)
        {
          yield return this[i];
        }
      }
    }]]>
  </Code>
  </Snippet>
  </CodeSnippet>
  有了這個(gè)snippet的治理支持和方便的使用方法后,基本就解決了我前面提到源代碼復(fù)用里面版本控制和變量名修改的問(wèn)題。
  
  其實(shí)這個(gè)snippet的使用還有一個(gè)積極的意義,我們知道編寫相同的邏輯過(guò)程是枯燥的,我們都喜歡編寫新的邏輯過(guò)程,即使新的邏輯更難更復(fù)雜,反而更有挑戰(zhàn)。但是我們又不能避開很多程序邏輯的復(fù)用,在我們以一種類似"厭惡"的情緒重復(fù)著那些程序邏輯時(shí),保證代碼的正確性真是一場(chǎng)噩夢(mèng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 顺昌县| 杭州市| 苏州市| 昆山市| 汉阴县| 洪雅县| 光泽县| 澄迈县| 天镇县| 齐齐哈尔市| 宁陵县| 盘山县| 无为县| 枝江市| 夹江县| 武宣县| 通山县| 莱西市| 临夏县| 济阳县| 平南县| 南京市| 凉城县| 潮安县| 珲春市| 浦东新区| 淅川县| 南丹县| 宜丰县| 鱼台县| 紫阳县| 左云县| 万盛区| 海阳市| 东港市| 城口县| 富平县| 同心县| 塔城市| 图木舒克市| 施秉县|