这里不跟大家分享 "类的实例能够继承父类的属性" 这种人人都知道的情况
主要分享 "持续抽象过程中,属性值覆盖的问题"
由于最近需要使用到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中, 所以可以访问. 在外部调用时, 只需要实例化模板类赋值相关属性, 即可发送信息, 身份标识与模板标识是访问不到的.
完