首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

善用 T4 範本消除重複代碼:從數值型別擴展方法到泛型重構

     編輯:關於.NET

痛點背景

需為 int、long、double 等數值型別撰寫相同語意的擴展方法(如 MustBetween、MustGreaterThan)。這些型別無共同繼承體系,初期只能逐型別複製貼上,極不優雅。

方案一:T4 文字範本產生重複代碼

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
using System;
namespace Happy.Infrastructure.ExtentionMethods {
    public static partial class Check {
<# foreach(var type in new string[]{ "double", "int" }) { #>
        /// <summary> 值必須在 [start, end] 範圍內 </summary>
        public static void MustBetween(this <#= type #> value, string variableName, <#= type #> start, <#= type #> end) {
            Require(value >= start && value <= end, String.Format(Messages.Error_MustBetween, variableName, start, end));
        }
        /// <summary> 值必須大於 target </summary>
        public static void MustGreaterThan(this <#= type #> value, string variableName, <#= type #> target) {
            Require(value > target, String.Format(Messages.Error_MustGreaterThan, variableName, target));
        }
        /// <summary> 值必須大於等於 target </summary>
        public static void MustGreaterThanEqual(this <#= type #> value, string variableName, <#= type #> target) {
            Require(value >= target, String.Format(Messages.Error_MustGreaterThanEqual, variableName, target));
        }
<# } #>
    }
}

T4 生成結果

配合 partial class,T4 產生的部分類別與手寫部分無縫合併,解決重複問題。

同事建議:泛型約束才是正解

同事建議截圖

所有數值型別都實作 IComparable<T>,直接寫泛型擴展方法並約束 where T : IComparable<T> 即可,無需 T4 產生重複代碼。

方案二:泛型擴展方法(最終採用)

public static void MustBetween<T>(this T value, string variableName, T start, T end) 
    where T : IComparable<T> {
    Require(value.CompareTo(start) >= 0 && value.CompareTo(end) <= 0, 
            String.Format(Messages.Error_MustBetween, variableName, start, end));
}

public static void MustGreaterThan<T>(this T value, string variableName, T target) 
    where T : IComparable<T> {
    Require(value.CompareTo(target) > 0, 
            String.Format(Messages.Error_MustGreaterThan, variableName, target));
}

public static void MustGreaterThanEqual<T>(this T value, string variableName, T target) 
    where T : IComparable<T> {
    Require(value.CompareTo(target) >= 0, 
            String.Format(Messages.Error_MustGreaterThanEqual, variableName, target));
}

反思與收穫

  • T4 是「寫代碼的代碼」,適用於無法用型別系統表達的重複模式(如固定型別清單、樁代碼生成)。
  • 當問題可用泛型 + 介面約束解決時,後者更優:零運行時開銷、單一原始碼維護、IDE 智慧感知完整支援。
  • 「經驗 + 意識」決定工具選型:先思考型別系統能否建模,再考慮代碼生成。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved