我碰巧经历了.net框架源代码,碰巧遇到了Nullable结构实现的显式运算符实现。下面的屏幕截图显示了Value属性的实现以及显式运算符的实现。我也明白显式运算符正试图从Nullable转换为T.我的问题是为什么不是以下代码没有抛出异常
框架实施
public T Value {
get {
if (!HasValue) {
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NoValue);
}
return value;
}
}
public static explicit operator T(Nullable<T> value) {
return value.Value;
}
客户代码
int? i = null;
int? i2 = (int?)i; //No Error
int? i = null;
int i2 = (int)i; //Runtime error
它表示value.Value,理想情况下,因为HasValue将为false(因为我指定了null)它应该抛出无效的操作异常,但它很乐意将值赋给i2。但是,如果我们将它更改为(int)i而不是(int?)i,则会引发Value属性的InvalidOperatorException。我的想法是当value.Value被调用时,它会抛出一个异常,因为正在访问该属性并且它将完成它的工作。
请同样澄清
谢谢,
答案 0 :(得分:2)
因为你转向int?
而不是int
public static explicit operator T(Nullable<T> value) {
return value.Value;
}
T
是int
,但您正在转向int?
,因此Value
从未被调用过。
答案 1 :(得分:2)
int? i2 = (int?)i;
只是从int?
到int?
的直接复制操作。不涉及转换运算符。这是struct变量的内存内容的平面副本。
答案 2 :(得分:1)
在int? i2 = (int?)i; //No Error
的情况下,永远不会在i上调用显式运算符方法,因为您正在转换为int?
而不是int
。
答案 3 :(得分:0)
您可能会被显式运算符弄糊涂。
它不是“显式运算符”,而是“显式运算符T”。在你的情况下,它变成“显式运算符int”,因为T是int。
只有在显式转换为int(名称中的线索;-))时才会调用显式运算符int。
因此,如前所述,i1不需要转换为int,并且不调用显式运算符int。