我正在查看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子句中。有人可以解释一下如何在幕后翻译这样的结构,所以我能理解为什么这样做是可以的?
答案 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)
我找到了一个可能的答案(这会让我成为答案代理吗?):Using statement with a null object
如果是我,我会写一个单元测试来验证这种行为,这样如果以后每次都改变了,那么测试就会失败。
见你