Что такое Visual Studio.NET snippets? Часть 2

Источник: habrahabr

Это вторая часть статьи про сниппеты. В первой давалось разъяснение, что это за механизм, для чего он нужен и как его применять. Во второй части речь пойдет про то, как сниппеты создавать.

Для примера возьмем очень простую обобщенную ситуацию: необходимость хранить скрытые временные данные в теле страницы. Ранее для этого использовали скрытые поля, но в asp.net есть механизм ViewState. Я не буду касаться темы использования ViewState, его влияния на производительность и размер страницы. Очевидно, что использовать его нужно аккуратно. Так вот, создадим сниппет для такой вот конструкции кода:

  public int ViewStatePropperty
  {
    get
    {
      object o = ViewState["ViewStatePropperty"];
      return (o != null) ? (int)o : 0;
    }
    set
    {
      ViewState["ViewStatePropperty"] = value;
    }
  }

Простейшее свойство, значение которого будет храниться не в закрытом поле, как обычно, а во ViewState. Обратите внимание, что в этом коде три изменяемых элемента: тип, имя и значение по умолчанию. Причем строка типа в коде используется дважды, а строка имени трижды. Теперь давайте определим, наконец-то сниппет. На самом деле сниппет - это определенный особым образом xml-файл и вот реализация для нашего примера:

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>propv</Title>
      <Shortcut>propv</Shortcut>
      <Description>Простой пример сниппета</Description>
      <Author>Xaoc, для проекта Habrahabr</Author>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
    </Header>
    <Snippet>
      <Declarations>
        <Literal>
          <ID>type</ID>
          <ToolTip>Property type</ToolTip>
          <Default>int</Default>
        </Literal>
        <Literal>
          <ID>property</ID>
          <ToolTip>Property name</ToolTip>
          <Default>MyProperty</Default>
        </Literal>
        <Literal>
          <ID>default</ID>
          <ToolTip>Default value</ToolTip>
          <Default>0</Default>
        </Literal>
      </Declarations>
      <Code Language="csharp"><![CDATA[public $type$ $property$
{
  get
  {
    object o = ViewState["$property$"];
    return (o != null) ? ($type$)o : $default$;
  }
  set
  {
    ViewState["$property$"] = value;
  }
}$end$]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

Итак, что же представляет собой описание данного сниппета. Основные тэги следующие: Header, который описывает скорее внешнюю часть и Snippet, который описывают логику.

В Header определяются тэги со значениями: наименования сниппета, шортката (это название по которому можно быстро вызвать сниппет), описания, автора, и типа сниппета. Тип сниппета может иметь три значения: SurroundsWith, Expansion и Refactoring. Первый указывает но то, что сниппет будет оборачивать выделенный текст (так делает стандартный сниппет region), второй - на то, что текст сниппета просто вставится, а третий используется для встроенного в студию механизма рефакторинга и не может использоваться в пользовательских сниппетах.

В Snippet декларируются литералы, значение которых можно будет редактировать при использовании сниппета, и собственно код сниппета. Обратите внимание на то, как определяется литерал: указывается его идентификатор, подсказка и значение по умолчанию. Идентификатор литерала затем используется в теле кода сниппета. Для выделения литерала, он заключается между двумя знаками доллара "$". Тэг Code содержит кроме определения кода сниппета еще и несколько атрибутов: Language, который указывает на целевой язык сниппета и может принимать значения VB, CSharp, VJSharp, или XML; Delimiter, который позволяет переопределить знак доллара на другой символ; и Kind, который позволяет указать сферу применения сниппета и принимает значения "method body", "method decl", "type decl", file, или any. В нашем случае Kind опущен, но его можно указать как "type decl".

После создания файла сниппета его нужно как-то внедрить в студию. Для этого используем стандартный диалог "Code Snippets Manager" в меню Tools главного меню сутдии. Если его у вас там нет, то значит ваш enviroment так настроен и пункт меню вы сможете отыскать в Tools\Customize - Commands - Tools. Можно сделать проще и вызвать диалог шорткатом ctrl+k, ctrl+b. В окне можно указать в какой раздел сохранить сниппет и нажав кнопку import импортировать ваш сниппет в студию. После этого вы можете набрать propv в редакторе и нажать tab. У вас должен добавиться текст вроде этого:

public int MyProperty
{
  get
  {
    object o = ViewState["MyProperty"];
    return (o != null) ? (int)o : 0;
  }
  set
  {
    ViewState["MyProperty"] = value;
  }
}

На этом все. Для полноты изложения дам ссылку на описание схемы xml-файла сниппета:
хттп://msdn.microsoft.com/ru-ru/library/ms171418(en-us,vs.80).aspx (к сожалению, из-за скобок в урл, Хабр неверно выделяет гиперлинк, скопируйте его в браузер как есть). Там можно подчерпнуть дополнительные знания и научится делать еще более сложные и полезные сниппеты.

PS: "в статье нет ошибок!" - к сожалению утверждать этого невозможно, но я буду рад, если вы обратите мое внимание на найденную вами ошибку.


Страница сайта http://test.interface.ru
Оригинал находится по адресу http://test.interface.ru/home.asp?artId=23834