C#属性的setter能否引用该属性自身的MaxLength特性?
实现方案
可以通过反射获取MaxLength特性中定义的长度值,完全避免硬编码,同时在赋值阶段提前验证数据,防止后续EF抛出异常。以下是具体实现:
基础版本实现
首先确保引入必要的命名空间:
using System.ComponentModel.DataAnnotations; using System.Reflection;
然后修改属性的实现逻辑:
private string _terId; /// <summary> /// Device Serial /// </summary> [Required] [MaxLength(50)] public string TerId { get => _terId; set { // 反射获取当前属性的MaxLength特性 var maxLengthAttr = typeof(YourClassName) .GetProperty(nameof(TerId)) .GetCustomAttribute<MaxLengthAttribute>(); // 验证长度(处理value为null的情况) if (maxLengthAttr != null && value != null && value.Length > maxLengthAttr.Length) { throw new ValidationException($"Max Length of Evidence.TerId would be exceeded by \"{value}\""); } _terId = value; } }
注意:将代码中的
YourClassName替换为你实际的类名称。
性能优化版(缓存特性值)
如果该属性会被频繁赋值,每次反射会产生额外性能开销,可以通过静态构造函数缓存最大长度值,只在类首次加载时执行一次反射:
private string _terId; private static readonly int _terIdMaxLength; // 静态构造函数,仅执行一次 static YourClassName() { var maxLengthAttr = typeof(YourClassName) .GetProperty(nameof(TerId)) .GetCustomAttribute<MaxLengthAttribute>(); // 若未定义MaxLength特性,默认允许任意长度;也可改为抛出异常强制要求添加特性 _terIdMaxLength = maxLengthAttr?.Length ?? int.MaxValue; } /// <summary> /// Device Serial /// </summary> [Required] [MaxLength(50)] public string TerId { get => _terId; set { if (value != null && value.Length > _terIdMaxLength) { throw new ValidationException($"Max Length of Evidence.TerId would be exceeded by \"{value}\""); } _terId = value; } }
补充说明
- 若需要强制要求属性必须添加
MaxLength特性,可将静态构造函数中的默认值逻辑改为抛出异常:_terIdMaxLength = maxLengthAttr?.Length ?? throw new InvalidOperationException("TerId property must have a MaxLength attribute"); - 这种实现方式保证了特性定义的长度与验证逻辑完全同步,后续修改
MaxLength的参数时,无需手动调整验证代码,降低维护成本。 - 在赋值阶段提前验证,能在数据进入EF上下文之前就捕获超长数据,避免EF在保存操作时才抛出异常。
内容的提问来源于stack exchange,提问作者Hecatonchires
相关产品推荐
相关产品推荐

