在using子句的上下文中调用null引用的方法是可以的吗?

时间:2011-07-10 06:57:50

标签: c# null nullreferenceexception

我正在查看Stack Overflow团队在Google Code上设计的mvc-mini-profiler,getting started页上的一件事让我感到特别奇怪:

var profiler = MiniProfiler.Current; // it's ok if this is null

using (profiler.Step("Set page title"))
{
    ViewBag.Title = "Home Page";
}

如果探查器为空,它怎么能“ok”?在我看来,调用Step会抛出一个NullReferenceException。在我编程C#的所有这些年里,我从来都不知道在任何上下文中调用null引用上的方法都是“ok”。这是在using子句的上下文中的特殊情况吗?

我能理解这是好的(不知道是这样,但显然是吗?):

using (null)
{
    ...
}

但是在null引用上调用方法似乎应该抛出异常,无论它是否在using子句中。有人可以解释一下如何在幕后翻译这样的结构,所以我能理解为什么这样做是可以的?

3 个答案:

答案 0 :(得分:12)

如果profiler为空,则绝对 确定,除非 profiler.Step实际上是一种扩展方法。 using语句不会影响该语句。

事实证明,扩展方法部分正是正在发生的事情。 MiniProfiler.cs的第584-587行:

public static IDisposable Step(this MiniProfiler profiler, string name,
                               ProfileLevel level = ProfileLevel.Info)
{
    return profiler == null ? null : profiler.StepImpl(name, level);
}

profiler.Step为空时,profiler可以调用它。它不是实例方法 - 调用转换为:

MiniProfilerExtensions.Step(profiler, ...);

根据问题的第二部分,profiler.Step 返回 null是可以的。

答案 1 :(得分:5)

Step必须是extension method,我在评论中的猜测也是如此。

否则你的编译器被肢解或者你是幻觉。 : - )

答案 2 :(得分:1)

哇,这么好的问题。我的第一反应是“当然是不合时宜的”......但我把它输入VS2010并且看起来很开心。

我找到了一个可能的答案(这会让我成为答案代理吗?):Using statement with a null object

如果是我,我会写一个单元测试来验证这种行为,这样如果以后每次都改变了,那么测试就会失败。

见你