使用 Visual Studio 和文字範本範本轉換工具套件 (T4) 自動生成代碼

更新頁 :
頁面創建日期 :

操作環境

Visual Studio的
  • Visual Studio 2022
。網
  • .NET 8.0
窗戶
  • 窗戶11

先決條件

Visual Studio的
  • 它甚至可以使用稍舊的版本
。網
  • 它甚至可以使用稍舊的版本

起先

通常,在創建代碼時,您認為您將通過手動輸入字元來創建代碼,但是如果您想根據特定法律需要創建的代碼或數據創建代碼,那麼能夠自動生成它很方便。 本節介紹如何使用文本範本轉換工具包(T4)自動生成代碼。

由於 T4 是一種腳本格式,因此在創建 T4 檔後立即在 Visual Studio 中生成代碼非常容易。 據記載,它會自動生成代碼,但生成的只是文本,因此除了程式之外,還可以生成任何文本格式的內容,例如XML和JSON。

這個技巧的主要目的是解釋在 T4 中實際自動生成代碼的步驟,所以我不會深入探討 T4 的細節。 如果你曾經用 C# 編寫過一個程式,你就會立即理解它。 如果您想瞭解更多關於T4的資訊,請查看官方網站和其他網站。

前提

此提示假定滿足以下條件:

  • 在 Windows 上安裝的 Visual Studio
  • 瞭解 C#

T4 可以在大多數專案中使用,但少數專案除外,因此您在安裝過程中基本上可以自由選擇工作負載。

創建專案

如前所述,T4 可以在大多數專案中使用,但少數專案除外,因此創建什麼類型的專案並不重要。 在本例中,我們將為主控台應用創建一個專案。

建立 T4 檔案 (.tt)

右鍵按下項目檔或資料夾以添加新項。

按兩下「查看所有範本」按鈕。

從左側的樹中選擇「常規」,從中間的清單中選擇“文本範本”。 檔名是任意的。

創建檔案后,您可能會立即看到一個類似於下面的對話方塊。 當自動生成 T4 檔時,將顯示此消息。 每次保存或查看檔時,都會自動生成 T4 檔。 如果要按原樣執行自動生成過程,請按一下確定按鈕。 如果您不希望對話框每次都顯示,請選中“不再顯示此消息”。 請注意,如果 T4 檔中描述了對話框中所述的非法進程,則將相應地執行該進程。

添加檔后,可以看到 .tt 檔已添加到解決方案資源管理器中。

該文件的內容如下。

如果在解決方案資源管理器中提取 .tt 檔,您將看到一個同名的文字檔。 這將是自動生成的檔。 由於我們還沒有編寫任何內容,因此文件的內容是空的。

將自動生成的檔設為.cs檔

如果您使用的是 T4,您很可能希望使用 .cs 擴展而不是預設的 .txt,因為您的程式代碼將自動生成。 在這種情況下,請打開 .tt 檔並使用 output extension .cs 保存。

自動生成的檔現在應具有.cs擴展名。 檔名本身與 .tt 檔相同,因此,如果要更改它,請更改 .tt 檔的名稱。

暫時,編寫一些東西並將其輸出到自動生成的檔中

在 T4 中,您編寫的內容基本上按原樣輸出。 <# ... #> 是 T4 進程,其餘部分是實際輸出文本。

例如,讓我們將其放在 .tt 檔中,如下所示。

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>

public static class Sample
{
  public static void Hello()
  {
    Console.WriteLine("Hello T4!!");
  }
}

當您保存它時,自動生成的檔應完全按照您編寫的方式輸出。

輸出是代碼,所以當然也可以從Program.cs調用。

嘗試自動生成代碼

如上所述,我已經確認我寫的內容將按原樣輸出,但這與我通常編寫的內容沒有什麼不同。 現在,讓我們實際使用 T4 腳本來自動生成代碼。 製作方法有很多種,所以請在這裡只做一個簡短的解釋,然後按照你想要的方式重新製作。

這一次,作為一個示例,讓我們創建一個方法,該方法將每種類型的 parse 方法添加到字串中,如果無法轉換,則返回 ParseXXXX 指定的預設值。 這隻是一個創作範例,因此,如果您覺得缺少任何部分,請添加它。

如果你能在不解釋細節的情況下理解 C#,看到它會更快,所以我會先發佈完整的代碼。

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>

<#
  List<string> types = new(){"Int", "Short", "Long", "Float", "Double", "Decimal"}; 
#>

public static class ParseExtensions
{
<# foreach (var type in types) { #>
<#   var typeLower = type.ToLower(); #>
  public static <#= typeLower #> Parse<#= type #>(this string self, <#= typeLower #> defaultValue)
  {
    return <#= typeLower #>.TryParse(self, out var val) ? val : defaultValue;
  }
<# } #>
}

我們正在做的是定義首次創建的類型 List ,然後將它們轉換 foreach 以生成該數量的方法。 T4 的腳本部分是用 C# 編寫的,所以如果你懂 C#,你應該能夠理解它。

執行此操作時,將產生以下代碼:

public static class ParseExtensions
{
  public static int ParseInt(this string self, int defaultValue)
  {
    return int.TryParse(self, out var val) ? val : defaultValue;
  }
  public static short ParseShort(this string self, short defaultValue)
  {
    return short.TryParse(self, out var val) ? val : defaultValue;
  }
  public static long ParseLong(this string self, long defaultValue)
  {
    return long.TryParse(self, out var val) ? val : defaultValue;
  }
  public static float ParseFloat(this string self, float defaultValue)
  {
    return float.TryParse(self, out var val) ? val : defaultValue;
  }
  public static double ParseDouble(this string self, double defaultValue)
  {
    return double.TryParse(self, out var val) ? val : defaultValue;
  }
  public static decimal ParseDecimal(this string self, decimal defaultValue)
  {
    return decimal.TryParse(self, out var val) ? val : defaultValue;
  }
}

生成的是代碼,因此您可以按原樣在程式中使用它。

關於 T4 的更多資訊

即使 T4 腳本部分可以用 C# 編寫,也必須將 T4 C# 代碼與實際生成的 C# 代碼分開。 做出這種區分 <# .... #> 的部分是 。 <# .... #> 是作為腳本執行的代碼,而不是在 T4 的腳本部分實際輸出的代碼。

<# .... #> 由於 C# 本身的內容保持不變,因此沒有對其進行解釋,但是 <# .... #> 有幾種類型的幀。 每種方法都有以下幾種使用方法。

代碼 說明
<#@ .... #> 它主要用於各種頭的聲明。 它用在和 import 聲明的 assembly T4 代碼的開頭。
<# .... #> 編寫由 T4 處理的代碼。 它可以分為多條線。 此範圍內描述的任何內容僅充當操作,不會影響輸出文本。
<#= .... #> 當您想要將值(如變數)輸出為輸出結果時,可以使用此選項。 string text = "Sample"; 例如,如果你寫了一個名為的變數 <#= text #> ,將會 Sample 輸出。
<#+ .... #> 用於定義類和方法。 基本上,它寫在 T4 檔的末尾。

關於 T4 編輯器

如果 Visual Studio 中沒有擴展名,打開 .tt 檔將以黑白文本顯示,沒有顏色,這很難看到。

其中一些可能會以易於閱讀的方式顯示 .tt 檔的擴展名,因此請找到您喜歡的那個。 由於它是由志願者製作的,因此內容可能會根據一年中的時間和 Visual Studio 的版本而變化。 可以從 Visual Studio 功能表中的「擴展」下添加擴展。

這是我在 Visual Studio 2022 中看到的內容,其中包含一個名為“T4 語言”的擴展。