這裡不跟大家分享 "類的實例能夠繼承父類的屬性" 這種人人都知道的情況
主要分享 "持續抽象過程中,屬性值覆蓋的問題"
由於最近需要使用到SubMail這個信息發送平台, 而這個平台的短信必須以模(mu)板的形式發送, 不能隨意編寫短信內容, 所以根據業務需要我編寫了N個模板, 這不是重點
辣麼問題來了:(發短信哪家強?) 每個模版的參數都不太一樣(模板ID, 參數數量, 參數名), 比如:
您的賬號@var(name)已審核通過。歡迎使用@var(sys)
訂單@var(order)已付款,@var(name)(@var(tel))將於@var(date)消費
但是身份標識 appid appkey 是一樣的, 為了區分變量及常量以及訪問級別的問題, 於是我就想到用繼承+只讀來實現
/// <summary> /// 用於發送時泛型約束的抽象類 /// 發送的方法簽名是這樣寫的: public static bool SendModel<T>(string target, T model) where T : SubMailModel /// </summary> public abstract class SubMailModel { } /// <summary> /// 對應SubMail身份 /// </summary> public abstract class Base10107 : SubMailModel { const string appid = ""; //身份ID const string appkey = ""; //身份密鑰 } /// <summary> /// 模版 /// </summary> public class Template_PaySuccessUser : Base10107 { const string templateID = "DVaVf3"; //模板參數 public string order { get; set; } public string name { get; set; } public string tel { get; set; } } 調用時無法訪問的寫法
以上寫法, 有個很明顯的問題: 泛型約束為頂級抽象類, 這個類中什麼都沒有, 所有的常量都在對應的子類中, 父類是不能訪問子類的, 所以調用發送的時候, 會找不到變量
於是有了下面這段 "改進" 後的代碼
/// <summary> /// 用於發送時泛型約束的抽象類 /// 發送的方法簽名是這樣寫的: public static bool SendModel<T>(string target, T model) where T : SubMailModel /// </summary> public abstract class SubMailModel { public string appid; //身份ID public string appkey; //身份密鑰 public string templateID; } /// <summary> /// 對應SubMail身份 /// </summary> public abstract class Base10107 : SubMailModel { string appid = "aaaaaaaaaa"; string appkey = "bbbbbbbbbbb"; } /// <summary> /// 模版 /// </summary> public class Template_PaySuccessUser : Base10107 { string templateID = "DVaVf3"; //模板參數 public string order { get; set; } public string name { get; set; } public string tel { get; set; } } 隱式隱藏父類參數的寫法以上寫法, 雖然在調用時能訪問參數了, 但是又多了另外一個問題: 沒有繼承, 而是隱式隱藏了父類的參數. 這樣在發送調用的時候因為泛型約束的關系, 變量沒有值
突然想到一個繼承常用的關鍵字 base, 於是有了最後一段代碼
/// <summary> /// 用於發送時泛型約束的抽象類 /// 發送的方法簽名是這樣寫的: public static bool SendModel<T>(string target, T model) where T : SubMailModel /// </summary> public abstract class SubMailModel { public string appid; //身份ID public string appkey; //身份密鑰 public string templateID; } /// <summary> /// 對應SubMail身份 /// </summary> public abstract class Base10107 : SubMailModel { public Base10107() { base.appid = "aaaaaaaaaa"; base.appkey = "bbbbbbbbbbb"; } } /// <summary> /// 模版 /// </summary> public class Template_PaySuccessUser : Base10107 { public Template_PaySuccessUser() { base.templateID = "DVaVf3"; } //模板參數 public string order { get; set; } public string name { get; set; } public string tel { get; set; } } 邏輯正確,但訪問級別過大的寫法大家也看到我的標題, 訪問級別過大還沒有解決, 當然這個也最簡單
直接把抽象類的屬性用internal修飾, 這樣在發送調用的時候因為是一個DLL中, 所以可以訪問. 在外部調用時, 只需要實例化模板類賦值相關屬性, 即可發送信息, 身份標識與模板標識是訪問不到的.
完