如何获取使用自定义结构体的类属性名称以优化异常信息?
如何让NonNullableString抛出的异常包含属性名称
我定义了一个NonNullableString结构体,通过隐式转换实现字符串非空校验,避免在类构造函数中重复编写空值检查逻辑,但当传入null时,抛出的ArgumentNullException无法指明具体是哪个属性(比如User类的Username)导致的问题,异常信息仅显示value参数,不利于排查定位。
现有NonNullableString结构体代码
public struct NonNullableString { public string Value { get; set; } private NonNullableString(string value) { if (value == null) throw new ArgumentNullException($"{value} cannot be null!", nameof(value)); Value = value; } public static implicit operator NonNullableString(string value) { return new NonNullableString(value); } public static implicit operator string(NonNullableString value) { return value.Value; } }
使用示例(User类)
public class User { public NonNullableString Username { get; set; } // ... 其他属性 public User(string username) { Username = username; } }
当前问题
调用new User(null)时,抛出的异常信息为:
Unhandled exception. System.ArgumentNullException: value (Parameter ' cannot be null!')
无法得知是Username属性导致的空值问题,不利于异常排查和日志记录。
解决方案
方案1:使用CallerMemberName特性自动获取属性名
通过[CallerMemberName]特性,让构造函数自动捕获调用方的属性名称,无需手动传递,同时将Value设为只读避免后续被篡改。
修改后的结构体代码:
using System.Runtime.CompilerServices; public struct NonNullableString { public string Value { get; } // 改为只读,防止实例创建后被设为null private NonNullableString(string value, [CallerMemberName] string propertyName = "") { if (value == null) throw new ArgumentNullException(propertyName, $"属性 {propertyName} 不能为空!"); Value = value; } public static implicit operator NonNullableString(string value) { return new NonNullableString(value); } public static implicit operator string(NonNullableString value) { return value.Value; } }
此时调用new User(null)会抛出明确指向属性的异常:
Unhandled exception. System.ArgumentNullException: Username (属性 Username 不能为空!)
方案2:显式传递属性名(适合自定义场景)
如果需要对特定属性做自定义异常处理,可以在类的属性setter中显式传递属性名,这种方式灵活性更高,但会失去隐式转换的简洁性:
public class User { private NonNullableString _username; public NonNullableString Username { get => _username; set => _username = new NonNullableString(value.Value, nameof(Username)); } public User(string username) { Username = username; } }
补充说明
启用Nullable引用类型后,编译器会对可能为null的字符串赋值发出警告,但不会阻止运行时传入null。NonNullableString结构体可以在运行时强制校验,同时配合编译器警告提前发现潜在问题。
内容的提问来源于stack exchange,提问作者Melih Çoban
相关产品推荐
相关产品推荐

