如何让C#泛型方法GetRequiredValue返回非可空类型?
解决方案:让GetRequiredValue返回非可空类型
问题分析
你当前的方法中,TValue会被编译器推断为属性的可空类型(比如string?),所以返回类型自然也是可空的。要实现返回非可空类型,需要调整泛型参数的定义,让方法明确返回基础的非可空类型。
实现方案
重新定义泛型方法,将表达式的返回类型指定为可空的T?,同时约束T为非可空类型,这样编译器就能推断出正确的非可空返回类型:
public static T GetRequiredValue<TClass, T>(this TClass obj, Expression<Func<TClass, T?>> expression) where T : notnull { // 从表达式中获取属性值(替换你原有的反射逻辑) var propertyInfo = ((MemberExpression)expression.Body).Member as PropertyInfo; if (propertyInfo == null) throw new ArgumentException("Expression must target a property."); var value = propertyInfo.GetValue(obj); if (value is null) throw new InvalidOperationException("Value cannot be null."); return (T)value; }
调用示例
对于你的MyClass:
public class MyClass { public string? Name { get; set; } public int? Age { get; set; } } // 调用示例 var myObj = new MyClass { Name = "StackExchange", Age = 15 }; string nonNullableName = myObj.GetRequiredValue(x => x.Name); // 返回string(非可空) int nonNullableAge = myObj.GetRequiredValue(x => x.Age); // 返回int(非可空) // 如果属性为null,调用时会抛出异常 var nullObj = new MyClass(); nullObj.GetRequiredValue(x => x.Name); // 抛出InvalidOperationException
原理说明
- 泛型参数
T被约束为notnull,确保它只能是非可空的引用类型或值类型。 - 表达式
Expression<Func<TClass, T?>>指定属性的类型是T的可空版本,编译器会自动将string?映射到T=string,int?映射到T=int。 - 方法内部检查值不为null后,将其强制转换为
T,此时编译器能够确认该值非空,不会产生可空警告。
内容的提问来源于stack exchange,提问作者Devator
相关产品推荐
相关产品推荐

