c# - 如何确保显式运算符在转换null时抛出异常?(不可为空)
问题描述
我在 class 上有一个显式运算符MyVO
,它应该是不可为空的。
public class MyVO : ValueObject<MyVO>
{
public string Value { get; } // Should never be null
private MyVO(string v) => Value = v;
public static explicit operator MyVO(string vo)
{
if (string.IsNullOrWhiteSpace(vo)) throw new Exception('...');
return new MyVO(vo);
}
但是,(MyVO)null
不会引发异常。该方法的主体将不会运行。
var myVO = (MyVO)null; // myVO will have the null value
如何确保它不为空?
解决方案
如何确保它不为空?
通过“它”,我假设您的意思是“从null
to 转换的结果MyVO
”。如果这不是你的意思,请澄清问题。
你不能。
C# 的一个重要规则是用户定义的转换在与内置转换冲突时永远不会“获胜”。转换null
为任何类类型都是合法的,因此MyVO
表达式的强制转换null
将始终导致空引用。如果内置转换有效,编译器甚至不会考虑用户定义的转换。(相信我;我写了那个代码!)
正如 D Stanley 的回答正确指出的那样,如果null
是任何类型表达式的值string
,则调用用户定义的转换;没有内置的 from string
to转换,MyVO
因此编译器查找适用的用户定义的转换并找到一个。
因为当你做你正在做的事情时会很痛,所以你应该停止做你正在做的事情。显式转换可能不是实现所需行为的正确方法。
我想我的问题应该是如何使
MyVO
不可为空。
升级到 C# 8。C# 8 支持对引用类型进行不可为空的注释。
请注意,不可为空的注解应该被正确地认为是注解。类型系统不保证使用不可为空注释注释的变量的值永远不会被观察为空。相反,它会尽力在代码看起来错误时向您发出警告。
当我们查看您的代码时,我注意到您正在使用ValueObject<T>
,我假设您是从类似的东西中获得的
https://enterprisecraftsmanship.com/posts/value-object-better-implementation/
让我借此机会提醒您,使用这种模式存在缺陷;您认为或想要应用T
的约束不是应用到的约束T
。我们经常看到这样的事情:
abstract class V<T> where T : V<T>
{
public void M(T t) { ... } // M must take an instance of its own type
}
如果我们有class Banana : V<Banana>
thenBanana.M
作为它的参数 a Banana
,这就是我们想要的。但现在假设我们有class Giraffe : V<Banana>
. 在这种情况下,Giraffe.M
不带长颈鹿;它需要一根香蕉,尽管Giraffe
根本没有任何关系Banana
。
约束并不意味着总是M
采用它自己的类的实例。如果您试图在 C# 中构造具有这种约束的泛型类型,则不能;C# 类型系统不够丰富,无法表达该约束。
推荐阅读
- xml - 如何添加 settings.xml 以将 Jenkins 的构建过程添加到 docker 映像
- python - 尝试通过步骤对字符串中的元素求和
- python - Python:对其中包含 n 个字典的字典进行排序的有效方法
- swift - 快速捏合缩放
- delphi - Delphi 的 Dropbox API,如何将数据发送回我的 Windows 应用程序?
- javascript - 无法在 d3 散点图的 x 轴上显示日期
- python - 在具有混合 int 和字符串 python 的数据帧上使用 groupby.sum()
- java - 从 android 应用程序执行外部程序
- python - XGBRegressor.fit() 失败并显示“没有可用于执行的内核映像”
- python - 如何转置熊猫数据框,保持两个数据列之一完整?