【问题标题】:How is it that can I execute method on int? set to null without NullReferenceException?我如何在 int 上执行方法?在没有 NullReferenceException 的情况下设置为 null?
【发布时间】:2017-01-24 19:48:10
【问题描述】:

我在 MSDN 上看到:

null 关键字是一个字面量,表示一个空引用,一个 不引用任何对象。

但我已经看到以下代码在运行时没有抛出任何异常:

int? i = null;
var s = i.ToString();

那么如果变量i 为null,为什么我可以执行它的方法呢?

【问题讨论】:

标签: c# nullable


【解决方案1】:

因为int?实际上是一个Nullable<Int32>,而Nullable<T>是一个struct,还有一个结构cannot be null

Nullable types work.就是这样,它们不是引用值,所以它们不能为null,但是当它们被认为等于null时,它们可以有一个状态。

您可以在how are nullable types implemented under the hood in .net?Nullable<T> implementation 中获得有关Nullable&lt;T&gt; 实现的更多详细信息


尽管@JeppeStigNielsen 指出,在一种情况下您可以获得 NRE:

但是:当装箱到引用类型时,特殊处理 Nullable 确保我们得到一个真正的空引用。所以例如 i.GetType() 和问题中的 i 一样会爆炸 空引用异常。那是因为这个方法是定义在 对象且不可覆盖

【讨论】:

  • 如果你查看Nullable(T).ToString 文档,它提到当HasValue 为假时你会得到一个空字符串。
  • 但是为什么在调试器变量中我显示为空?
  • @BudaGavril 因为调试器知道Nullable&lt;T&gt; 类型并且稍微作弊使它在没有值时看起来为空。
  • @BudaGavril 这不是一个错误,因为这是人们在将变量设置为 null 后通常期望看到的。不过,也许以某种方式表明这样的null 不是真正意义上的null,这样的误导性可能会更小。
  • 然而:当装箱到引用类型时,Nullable&lt;&gt; 的特殊处理确保我们得到一个真正的空引用。例如i.GetType()i 就像问题NullReferenceException 一起爆炸。那是因为这个方法是在object 上定义的,并且不能被覆盖。
【解决方案2】:

你粘贴的代码

int? i = null;

其实只是简写

int? i = new int?();

这是

的简写
Nullable<int> i = new Nullable<int>();

分配 null 是使用隐式运算符,您可以从这里阅读更多信息 MSDN

【讨论】:

  • 你在哪里找到的?能给个链接吗?
  • msdn.microsoft.com/en-us/library/1t3y8s4s.aspx "语法 T? 是 Nullable 的简写,其中 T 是值类型。这两种形式可以互换。"
  • 分配 null 不使用该隐式运算符。像int? i = 42; 这样的赋值可以被认为是使用隐式运算符。但是,C# 将有自己的内置隐式转换,从 intint?,所以我认为 C# 编译器实际上不会“发出”对您链接的 IL 方法的调用。并且在分配 null 的情况下,必须考虑从文字 null 到类型 int? 的 C# 内置隐式转换才能理解它的工作原理。
猜你喜欢
  • 1970-01-01
  • 2018-12-06
  • 1970-01-01
  • 2015-01-08
  • 1970-01-01
  • 1970-01-01
  • 2011-11-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多