[英]How to make sure the explicit operator throws the exception when converting null? (not nullable)
我在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
到MyVO
”。 如果这不是您的意思,请澄清问题。
你不能。
C# 的一个重要规则是用户定义的转换在与内置转换冲突时永远不会“获胜” 。 将null
转换为任何类类型都是合法的,因此MyVO
对表达式null
的MyVO
将始终导致 null 引用。 如果内置转换有效,编译器甚至不会考虑用户定义的转换。 (相信我;我写了那个代码!)
正如 D Stanley 的回答正确指出的那样,如果null
是string
类型的任何表达式的值,则调用用户定义的转换; 没有从string
到MyVO
内置转换,因此编译器会查找适用的用户定义转换并找到一个。
因为当你做你正在做的事情时会很痛,你应该停止做你正在做的事情。 显式转换可能不是实现所需行为的正确方法。
我想我的问题应该是如何使
MyVO
不可为空。
升级到 C# 8。C# 8 支持对引用类型进行不可为空的注释。
请注意,不可为空的注释应该被正确地视为annotation 。 类型系统不保证用不可为空的注释注释的变量的值永远不会被观察到为空。 相反,它会尽最大努力在代码看起来有误时向您发出警告。
在我们查看您的代码时,我注意到您正在使用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>
那么Banana.M
将一个Banana
作为它的参数,这就是我们想要的。 但是现在假设我们有class Giraffe : V<Banana>
。 在这种情况下, Giraffe.M
不带长颈鹿; 它需要一根香蕉,尽管Giraffe
与Banana
根本没有关系。
约束并不意味着M
始终把自己的类的实例。 如果您尝试在 C# 中使用这种约束构造泛型类型,则不能; C# 类型系统不够丰富,无法表达该约束。
null
可以隐式转换为任何引用类型,因此编译器不会使用您的显式转换运算符。 尝试
string s = null;
o = (MyVO)s;
或者只是内联它
o = (MyVO)((string)s);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.