背景
我需要為int、long、float等這些數值類型寫一些擴展方法,但是我發現他們不是一個繼承體系,我的第一個思維就是需要為每個類型重復寫一遍擴展方法,這讓我覺得非常不爽,但是我還是不情願的寫了,等int和long寫完后,我突然覺得我可以讓T4幫我寫,而且C#支持部分類,就更爽了。
用T4實現
模板(寫代碼的代碼)
1 <#@ template debug="false" hostspecific="false" language="C#" #> 2 <#@ assembly name="System.Core" #> 3 <#@ import namespace="System.Linq" #> 4 <#@ import namespace="System.Text" #> 5 <#@ import namespace="System.Collections.Generic" #> 6 <#@ output extension=".cs" #> 7 using System; 8 using System.Collections.Generic; 9 using System.Linq; 10 using System.Text; 11 using System.Threading.Tasks; 12 using System.IO; 13 14 namespace Happy.Infrastructure.ExtentionMethods 15 { 16 public static partial class Check 17 { 18 <# 19 foreach(var type in new string[]{ "double", "int" }) 20 { 21 #> 22 /// <summary> 23 /// 名稱為<paramref name="variableName"/>的參數或變量的值(<paramref name="value"/>)必須在某個范圍。 24 /// </summary> 25 public static void MustBetween(this <#= type #> value, string variableName, <#= type #> start, <#= type #> end) 26 { 27 Require(value >= start && value <= end, String.Format(Messages.Error_MustBetween, variableName, start, end)); 28 } 29 30 /// <summary> 31 /// 名稱為<paramref name="variableName"/>的參數或變量的值(<paramref name="value"/>)必須大於指定的值。 32 /// </summary> 33 public static void MustGreaterThan(this <#= type #> value, string variableName, <#= type #> target) 34 { 35 Require(value > target, String.Format(Messages.Error_MustGreaterThan, variableName, target)); 36 } 37 38 /// <summary> 39 /// 名稱為<paramref name="variableName"/>的參數或變量的值(<paramref name="value"/>)必須大於等於指定的值。 40 /// </summary> 41 public static void MustGreaterThanEqual(this <#= type #> value, string variableName, <#= type #> target) 42 { 43 Require(value > target, String.Format(Messages.Error_MustGreaterThanEqual, variableName, target)); 44 } 45 46 <# 47 } 48 #> 49 } 50 }
我對了嗎?
當我為這種用法暗自高興的時候,有位兄弟給了我更好的意見:
看到這段話的那一刻是我當天最開心的時刻,謝謝郭明鋒兄弟。
我在反思為啥當時我只思考他們不是一個繼承體系,而忽略了他們或許會都實現某個接口呢,意識+經驗非常重要,相信這次是一個比較好的經歷。
改進后的版本
1 /// <summary> 2 /// 名稱為<paramref name="variableName"/>的參數或變量的值(<paramref name="value"/>)必須在某個范圍。 3 /// </summary> 4 public static void MustBetween<T>(this T value, string variableName, T start, T end) 5 where T : IComparable<T> 6 { 7 Require(value.CompareTo(start) >= 0 && value.CompareTo(end) <= 0, String.Format(Messages.Error_MustBetween, variableName, start, end)); 8 } 9 10 /// <summary> 11 /// 名稱為<paramref name="variableName"/>的參數或變量的值(<paramref name="value"/>)必須大於指定的值。 12 /// </summary> 13 public static void MustGreaterThan<T>(this T value, string variableName, T target) 14 where T : IComparable<T> 15 { 16 Require(value.CompareTo(target) > 0, String.Format(Messages.Error_MustGreaterThan, variableName, target)); 17 } 18 19 /// <summary> 20 /// 名稱為<paramref name="variableName"/>的參數或變量的值(<paramref name="value"/>)必須大於等於指定的值。 21 /// </summary> 22 public static void MustGreaterThanEqual<T>(this T value, string variableName, T target) 23 where T : IComparable<T> 24 { 25 Require(value.CompareTo(target) >= 0, String.Format(Messages.Error_MustGreaterThanEqual, variableName, target)); 26 }
備注
再次感謝(郭明鋒)http://www.cnblogs.com/guomingfeng/。