You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 04:15:01