Nullable<T>结构的显式操作符实现引起的困惑

3
我刚好浏览了 .net framework 源代码,并发现了 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 时,它会抛出异常,因为正在访问该属性并且它将执行其工作。
请澄清一下。
谢谢,
Sai Pavan
4个回答

2
因为您转换为 int? 而不是 int
public static explicit operator T(Nullable<T> value) { 
    return value.Value; 
}

Tint 类型,但你将其转换为 int? 类型,因此 Value 从未被调用。


所以考虑到你所说的,假设我已经放置了int?(就像第一个案例中一样),它必须调用Value属性,对吧?在这种情况下,当它被调用时,它必须引发异常,因为HasValue将为false。请问您能告诉我在这种情况下它是如何工作的吗? - usaipavan
@usaipavan 的 HasValue 永远不会被调用,因为可空类型只是被复制而没有调用任何显式运算符,因为 T? 没有定义运算符(无论如何也行不通)。 - Felix K.

2
int? i2 = (int?)i;

这只是从int?int?的直接复制操作,不涉及任何转换运算符。这是对结构变量的内存内容进行的平面复制。

1
int? i2 = (int?)i; //No Error 的情况下,由于你将其转换为 int? 而不是 int,因此 i 上的显式转换运算符方法永远不会被调用。

0

你可能会被显式操作符搞混了。

它不是“显式操作符”,而是“显式操作符 T”。在你的情况下,它变成了“显式操作符 int”,因为 T 是 int。

只有当你明确地转换为 int 时,才会调用显式操作符 int(提示在名称中;-))。

因此,正如已经说过的那样,i1 不需要转换为 int,也不会调用显式操作符 int。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接