源代码模板
传统上,模板或代码片段存储并管理在源代码之外。 这是合理的,因为通常模板可以帮助您快速生成一些通用的样板代码。 为此,JetBrains Rider 提供了许多预定义的 实时模板、 环绕模板 和 文件模板。 您还可以 创建您自己的这些类型的模板。
然而,您可能希望生成一些仅与当前项目或解决方案相关的可重复代码。 JetBrains Rider 允许您通过 源代码模板 简化此类任务。
运作方式
与传统模板不同,源代码模板可以作为 扩展方法 在项目代码中的任何位置创建。 您可以为项目中的某些特定类型或任何标准类型定义它们。 您甚至可以通过将其创建为 对象 的扩展方法,使源代码模板可用于所有类型。
一旦定义了模板,它就会在相应类型及其继承者的 代码补全列表 中可用。 当您在列表中选择模板时,JetBrains Rider 会将模板方法主体中的代码插入到您的代码中。
以下是一个示例,说明了源代码模板的最简单应用。 我们的模板 forEach 将可用于所有泛型集合——这是由参数 this IEnumerable<T> x 定义的。 它将插入在方法主体中指定的迭代集合的代码。 我们可以在项目中的任何静态类中定义模板。 JetBrains Rider 将通过 [SourceTemplate] 属性将其识别为模板:
要部署此模板,我们现在可以对任何集合对象使用 自动补全:

当您选择模板项时,对象将被模板文本替换:
Note that the //$ $END$ comment in the template definition is nothing else but the predefined template parameter defining the caret position after the template is applied. 您可以在模板中 使用其他参数 以使模板更灵活。
为什么使用源代码模板
如上所述,源代码模板最适合在当前项目或解决方案中重用的代码块。 以下是一些显示源代码模板相较于传统模板优势的要点:
创建源代码模板
对于源代码模板的定义,您可以创建一个新类或使用现有的静态类来存放扩展方法。
模板方法及其主体
源代码模板必须是公共扩展方法,并具有 [SourceTemplate] 属性。 该属性定义在 JetBrains.Annotations 命名空间中,与 [NotNull]、 [CanBeNull] 和其他 代码注解属性 一起。 因此,要定义源代码模板方法,您需要 在项目中启用代码注解。
在模板主体中,您可以编写任何您想要的代码。 通常,它会对调用者对象执行某些操作,但这并不是必须的。
您可能还需要在模板方法中使用一些无法编译的代码。 例如,您可能希望使用调用者对象的名称来生成局部变量的名称。 在这种情况下,将此代码放在以 '$' 符号开头的行或块注释中:
目标表达式
当源代码模板扩展到复杂表达式时,默认情况下它只捕获表达式的最新部分。 如果您需要捕获整个表达式,您必须使用 目标 属性和 SourceTemplateTargetExpression.Outer 值显式指定。 在下面的示例中, Sqrt 模板将扩展到整个 x+y 表达式,结果为 var sqrt = Math.Sqrt(x+y)。

参数和宏
在源代码模板中,您可以使用 参数 和 宏。 根据您要为参数使用的宏,您可以选择几种指定和使用参数的方式。
您可以通过向模板方法添加新参数来创建模板参数。 默认情况下,它将作为可编辑参数运行,也就是说,在您应用模板时,它将在 热点会话 中获得焦点。 如果您想为此参数定义一个宏,您需要添加
[宏]属性,如下面的示例所示。表达式属性定义了应该使用哪个宏。 您可以指定一个 可用的模板宏。可编辑属性可选地指定在应用模板时用户是否可以编辑参数。 默认情况下,所有用户定义的参数都是可编辑的;值-1使参数不可编辑。如果同一个参数在模板中多次使用,则在应用模板时,只有一个实例是可编辑的;其他实例会同步更改。 如果需要,您可以通过在 'Editable' 属性中指定其从零开始的索引来定义哪个实例是可编辑的。
[SourceTemplate] public static void newGuid(this object obj, [Macro(Expression = "guid()", Editable = -1)] string newguid) { Console.WriteLine(newguid); }您可以将模板方法中的任何局部变量转换为模板参数。 为此,您需要在模板方法定义中添加
[宏]属性,并在其目标属性中指定变量名称。 例如:[SourceTemplate] [Macro(Target = "item", Expression = "suggestVariableName()")] public static void forEach<T>(this IEnumerable<T> collection) { foreach (var item in collection) { //$ $END$ } }您可以像在其他 JetBrains Rider 模板中一样使用 预定义参数 和所有用户定义的参数,将参数标识符用两个
$符号$param_name$包裹起来。您可以在字符串字面量中使用用户定义的模板参数,例如:
Console.WriteLine("A random GUID: $newguid$");要在字符串字面量之外使用模板参数,您需要将它们放在以
$符号开头的特殊模板注释中://$ $param_name$。 或/*$ $param_name$ */。 例如:[SourceTemplate] [Macro(Target = "newguid", Expression = "guid()", Editable = -1)] public static void newGuid(this object obj) { //$ var guid = "$newguid$"; Console.WriteLine("A random GUID: $newguid$"); }调用者对象以及作为方法参数和局部变量创建的模板参数,可以在特殊模板注释中带或不带
$符号使用。
应用源代码模板
要应用您的源代码模板,首先确保模板在作用域内。 也就是说,您要么在同一个命名空间中,要么显式导入了模板的命名空间。
从源代码模板创建代码片段
将光标放置在您想要部署模板的位置。
键入一个对象(您想要为其部署模板),然后键入一个点,然后开始键入模板的名称或其 CamelHumps 缩写。
在补全列表中选择模板并单击它或按 输入 。
调用者对象、点和您键入的模板名称部分将被模板主体替换。
如果模板具有 可编辑参数 (即需要用户输入),JetBrains Rider 会在编辑器中部署一个 热区会话 ,并将输入位置设置为第一个参数。 然后,您可以执行以下操作:
如果 JetBrains Rider 为当前参数建议了一些值,请使用 上 和 下 箭头键浏览建议值列表,或者直接键入所需的值。
按 标签页 或 输入 接受值并移动到下一个参数的输入位置。 如果这是最后一个参数,会话热点将完成,插入点将移动到为会话定义的结束位置。
按 Shift+Tab 键 将输入焦点移动到上一个参数的输入位置。
按 Esc 退出热区会话。 在这种情况下,所有会话参数将使用默认值进行初始化。