在using子句的上下文中对空引用调用方法是可以的
本文关键字:方法 调用 引用 子句 using 上下文 | 更新日期: 2023-09-27 18:01:51
我正在看Google Code上Stack Overflow团队设计的mvc-mini-profiler,在入门页面上有一件事让我特别奇怪:
var profiler = MiniProfiler.Current; // it's ok if this is null
using (profiler.Step("Set page title"))
{
ViewBag.Title = "Home Page";
}
如果profiler为空,它怎么可能是"ok"?在我看来,调用Step会抛出一个NullReferenceException
。在我多年的c#编程中,我从来没有听说过在任何上下文中对空引用调用方法是"ok"的。在使用从句的上下文中,这是一个特例吗?
我可以理解这是OK的(不知道它是,但显然它是?):
using (null)
{
...
}
但是在null引用上调用方法似乎应该抛出异常,无论它是否在using子句中。有人能解释一下这种结构是如何在幕后翻译的吗?这样我就能理解为什么这样做是可以的?
绝对不 OK,如果profiler
是null 除非 profiler.Step
实际上是一个扩展方法。using
语句不影响
事实证明,扩展方法部分正是正在发生的事情。miniprofile .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
为空时profiler.Step
被调用的方式。它不是一个实例方法——调用转换为:
MiniProfilerExtensions.Step(profiler, ...);
对于profiler.Step
来说,返回 null是很好的,正如你问题的第二部分。
Step
必须是扩展方法,正如我在评论中猜测的那样。
否则,要么你的编译器被破坏了,要么你产生了幻觉。: -)
哇,这是个好问题。我的第一反应是"这当然不好"……但我把它输入VS2010,似乎很高兴。
我在这里找到了一个可能的答案(这是否使我成为一个答案代理?):使用带有空对象的语句
如果是我,我会写一个单元测试来验证这个行为,这样如果它在将来每一次改变,测试就会失败。
再见