C#多DateTime属性校验优化:如何避免IF判断检测过期许可证
解决C#多许可证日期属性批量过期校验的方案
方案1:预定义强类型属性列表(最推荐)
这种方式完全避免反射,保留编译时类型检查,性能最优且易维护,只需把待校验的许可证属性统一放到列表中遍历即可。
假设你的基础定义如下:
// 实体类 public class TestA { public DateTime LicenseN1 { get; set; } public DateTime LicenseN2 { get; set; } public DateTime LicenseN3 { get; set; } public DateTime LicenseN4 { get; set; } public DateTime ChangedAt { get; set; } // 无需校验的属性 } // 过期消息返回类 public class ExpiredLicensesMessage { public List<(DateTime ExpiredDate, string Message)> ExpiredItems { get; set; } = new(); } // 过期判断方法 private bool IsExpired(DateTime date) => date < DateTime.Now; // 属性名与自定义消息的映射字典 private Dictionary<string, string> PendencyDictionary = new() { { nameof(TestA.LicenseN1), "许可证1已过期" }, { nameof(TestA.LicenseN2), "许可证2已过期" }, // ...其他映射 };
批量校验实现:
// 预定义待校验的许可证属性(强类型,编译时检查) private static readonly List<(Func<TestA, DateTime> DateGetter, string PropertyName)> _licenseProps = new() { (t => t.LicenseN1, nameof(TestA.LicenseN1)), (t => t.LicenseN2, nameof(TestA.LicenseN2)), (t => t.LicenseN3, nameof(TestA.LicenseN3)), (t => t.LicenseN4, nameof(TestA.LicenseN4)) }; public ExpiredLicensesMessage CheckExpiredLicenses(TestA entity) { var result = new ExpiredLicensesMessage(); foreach (var prop in _licenseProps) { var licenseDate = prop.DateGetter(entity); if (IsExpired(licenseDate)) { if (PendencyDictionary.TryGetValue(prop.PropertyName, out var message)) { result.ExpiredItems.Add((licenseDate, message)); } } } return result; }
方案2:反射筛选命名规律的属性
如果许可证属性命名有统一规则(比如都以LicenseN开头),可以用反射批量筛选这类属性,减少手动维护列表的工作量。
// 可缓存属性列表,避免每次反射开销 private static readonly PropertyInfo[] _licenseProps = typeof(TestA).GetProperties() .Where(p => p.PropertyType == typeof(DateTime) && p.Name.StartsWith("LicenseN")) .ToArray(); public ExpiredLicensesMessage CheckExpiredLicenses(TestA entity) { var result = new ExpiredLicensesMessage(); foreach (var prop in _licenseProps) { var licenseDate = (DateTime)prop.GetValue(entity); if (IsExpired(licenseDate)) { if (PendencyDictionary.TryGetValue(prop.Name, out var message)) { result.ExpiredItems.Add((licenseDate, message)); } } } return result; }
方案3:自定义属性标记待校验字段
如果属性命名无规律,可通过自定义特性标记需要校验的许可证属性,实现更灵活的批量筛选。
首先定义自定义特性:
[AttributeUsage(AttributeTargets.Property)] public class LicenseExpiryAttribute : Attribute { }
给实体属性打标记:
public class TestA { [LicenseExpiry] public DateTime LicenseN1 { get; set; } [LicenseExpiry] public DateTime LicenseN2 { get; set; } [LicenseExpiry] public DateTime LicenseN3 { get; set; } [LicenseExpiry] public DateTime LicenseN4 { get; set; } public DateTime ChangedAt { get; set; } }
批量校验实现:
// 缓存标记了特性的属性列表 private static readonly PropertyInfo[] _licenseProps = typeof(TestA).GetProperties() .Where(p => p.PropertyType == typeof(DateTime) && Attribute.IsDefined(p, typeof(LicenseExpiryAttribute))) .ToArray(); public ExpiredLicensesMessage CheckExpiredLicenses(TestA entity) { var result = new ExpiredLicensesMessage(); foreach (var prop in _licenseProps) { var licenseDate = (DateTime)prop.GetValue(entity); if (IsExpired(licenseDate)) { if (PendencyDictionary.TryGetValue(prop.Name, out var message)) { result.ExpiredItems.Add((licenseDate, message)); } } } return result; }
方案选择建议
- 优先选方案1:强类型无反射开销,编译时就能发现属性名错误,维护成本低。
- 属性数量多且命名规律时选方案2:减少手动添加属性的工作量。
- 属性命名无规律时选方案3:通过特性标记实现灵活筛选,适合复杂场景。
内容的提问来源于stack exchange,提问作者Percy22
相关产品推荐
相关产品推荐

